Sparc instruction opcodes now all live under the `V9' namespace.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6249 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Misha Brukman 2003-05-20 20:32:24 +00:00
parent f117cc9ee6
commit a98cd4578f
10 changed files with 573 additions and 572 deletions

View File

@ -91,7 +91,7 @@ void BBLiveVar::calcDefUseSets() {
// Put Phi operands in UseSet for the incoming edge, not node. // Put Phi operands in UseSet for the incoming edge, not node.
// They must not "hide" later defs, and must be handled specially // They must not "hide" later defs, and must be handled specially
// during set propagation over the CFG. // during set propagation over the CFG.
if (MI->getOpCode() == PHI) { // for a phi node if (MI->getOpCode() == V9::PHI) { // for a phi node
const Value *ArgVal = Op; const Value *ArgVal = Op;
const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB
@ -110,7 +110,7 @@ void BBLiveVar::calcDefUseSets() {
// do for implicit operands as well // do for implicit operands as well
for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) { for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) {
assert(MI->getOpCode() != PHI && "Phi cannot have implicit opeands"); assert(MI->getOpCode() != V9::PHI && "Phi cannot have implicit opeands");
const Value *Op = MI->getImplicitRef(i); const Value *Op = MI->getImplicitRef(i);
if (Op->getType() == Type::LabelTy) // don't process labels if (Op->getType() == Type::LabelTy) // don't process labels

View File

@ -91,7 +91,7 @@ void BBLiveVar::calcDefUseSets() {
// Put Phi operands in UseSet for the incoming edge, not node. // Put Phi operands in UseSet for the incoming edge, not node.
// They must not "hide" later defs, and must be handled specially // They must not "hide" later defs, and must be handled specially
// during set propagation over the CFG. // during set propagation over the CFG.
if (MI->getOpCode() == PHI) { // for a phi node if (MI->getOpCode() == V9::PHI) { // for a phi node
const Value *ArgVal = Op; const Value *ArgVal = Op;
const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB
@ -110,7 +110,7 @@ void BBLiveVar::calcDefUseSets() {
// do for implicit operands as well // do for implicit operands as well
for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) { for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) {
assert(MI->getOpCode() != PHI && "Phi cannot have implicit opeands"); assert(MI->getOpCode() != V9::PHI && "Phi cannot have implicit opeands");
const Value *Op = MI->getImplicitRef(i); const Value *Op = MI->getImplicitRef(i);
if (Op->getType() == Type::LabelTy) // don't process labels if (Op->getType() == Type::LabelTy) // don't process labels

View File

@ -309,7 +309,7 @@ private :
unsigned getOperandMask(unsigned Opcode) { unsigned getOperandMask(unsigned Opcode) {
switch (Opcode) { switch (Opcode) {
case SUBcc: return 1 << 3; // Remove CC argument case V9::SUBcc: return 1 << 3; // Remove CC argument
//case BA: return 1 << 0; // Remove Arg #0, which is always null or xcc //case BA: return 1 << 0; // Remove Arg #0, which is always null or xcc
default: return 0; // By default, don't hack operands... default: return 0; // By default, don't hack operands...
} }
@ -320,9 +320,11 @@ inline bool
SparcFunctionAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI, SparcFunctionAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
unsigned int opNum) { unsigned int opNum) {
switch (MI->getOpCode()) { switch (MI->getOpCode()) {
case JMPLCALL: case V9::JMPLCALL:
case JMPLRET: return (opNum == 0); case V9::JMPLRET:
default: return false; return (opNum == 0);
default:
return false;
} }
} }

View File

@ -14,7 +14,6 @@
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include <stdlib.h> #include <stdlib.h>
using std::vector;
static const uint32_t MAXLO = (1 << 10) - 1; // set bits set by %lo(*) static const uint32_t MAXLO = (1 << 10) - 1; // set bits set by %lo(*)
static const uint32_t MAXSIMM = (1 << 12) - 1; // set bits in simm13 field of OR static const uint32_t MAXSIMM = (1 << 12) - 1; // set bits in simm13 field of OR
@ -84,7 +83,7 @@ GetConstantValueAsSignedInt(const Value *V, bool &isValidConstant)
static inline void static inline void
CreateSETUWConst(const TargetMachine& target, uint32_t C, CreateSETUWConst(const TargetMachine& target, uint32_t C,
Instruction* dest, vector<MachineInstr*>& mvec, Instruction* dest, std::vector<MachineInstr*>& mvec,
bool isSigned = false) bool isSigned = false)
{ {
MachineInstr *miSETHI = NULL, *miOR = NULL; MachineInstr *miSETHI = NULL, *miOR = NULL;
@ -100,7 +99,7 @@ CreateSETUWConst(const TargetMachine& target, uint32_t C,
// Set the high 22 bits in dest if non-zero and simm13 field of OR not enough // Set the high 22 bits in dest if non-zero and simm13 field of OR not enough
if (!smallNegValue && (C & ~MAXLO) && C > MAXSIMM) if (!smallNegValue && (C & ~MAXLO) && C > MAXSIMM)
{ {
miSETHI = BuildMI(SETHI, 2).addZImm(C).addRegDef(dest); miSETHI = BuildMI(V9::SETHI, 2).addZImm(C).addRegDef(dest);
miSETHI->setOperandHi32(0); miSETHI->setOperandHi32(0);
mvec.push_back(miSETHI); mvec.push_back(miSETHI);
} }
@ -111,14 +110,15 @@ CreateSETUWConst(const TargetMachine& target, uint32_t C,
{ {
if (miSETHI) if (miSETHI)
{ // unsigned value with high-order bits set using SETHI { // unsigned value with high-order bits set using SETHI
miOR = BuildMI(OR, 3).addReg(dest).addZImm(C).addRegDef(dest); miOR = BuildMI(V9::OR,3).addReg(dest).addZImm(C).addRegDef(dest);
miOR->setOperandLo32(1); miOR->setOperandLo32(1);
} }
else else
{ // unsigned or small signed value that fits in simm13 field of OR { // unsigned or small signed value that fits in simm13 field of OR
assert(smallNegValue || (C & ~MAXSIMM) == 0); assert(smallNegValue || (C & ~MAXSIMM) == 0);
miOR = BuildMI(OR, 3).addMReg(target.getRegInfo().getZeroRegNum()) miOR = BuildMI(V9::OR, 3).addMReg(target.getRegInfo()
.addSImm(sC).addRegDef(dest); .getZeroRegNum())
.addSImm(sC).addRegDef(dest);
} }
mvec.push_back(miOR); mvec.push_back(miOR);
} }
@ -140,14 +140,14 @@ CreateSETUWConst(const TargetMachine& target, uint32_t C,
static inline void static inline void
CreateSETSWConst(const TargetMachine& target, int32_t C, CreateSETSWConst(const TargetMachine& target, int32_t C,
Instruction* dest, vector<MachineInstr*>& mvec) Instruction* dest, std::vector<MachineInstr*>& mvec)
{ {
// Set the low 32 bits of dest // Set the low 32 bits of dest
CreateSETUWConst(target, (uint32_t) C, dest, mvec, /*isSigned*/true); CreateSETUWConst(target, (uint32_t) C, dest, mvec, /*isSigned*/true);
// Sign-extend to the high 32 bits if needed // Sign-extend to the high 32 bits if needed
if (C < 0 && (-C) > (int32_t) MAXSIMM) if (C < 0 && (-C) > (int32_t) MAXSIMM)
mvec.push_back(BuildMI(SRA, 3).addReg(dest).addZImm(0).addRegDef(dest)); mvec.push_back(BuildMI(V9::SRA, 3).addReg(dest).addZImm(0).addRegDef(dest));
} }
@ -164,7 +164,7 @@ CreateSETSWConst(const TargetMachine& target, int32_t C,
static inline void static inline void
CreateSETXConst(const TargetMachine& target, uint64_t C, CreateSETXConst(const TargetMachine& target, uint64_t C,
Instruction* tmpReg, Instruction* dest, Instruction* tmpReg, Instruction* dest,
vector<MachineInstr*>& mvec) std::vector<MachineInstr*>& mvec)
{ {
assert(C > (unsigned int) ~0 && "Use SETUW/SETSW for 32-bit values!"); assert(C > (unsigned int) ~0 && "Use SETUW/SETSW for 32-bit values!");
@ -174,13 +174,14 @@ CreateSETXConst(const TargetMachine& target, uint64_t C,
CreateSETUWConst(target, (C >> 32), tmpReg, mvec); CreateSETUWConst(target, (C >> 32), tmpReg, mvec);
// Shift tmpReg left by 32 bits // Shift tmpReg left by 32 bits
mvec.push_back(BuildMI(SLLX, 3).addReg(tmpReg).addZImm(32).addRegDef(tmpReg)); mvec.push_back(BuildMI(V9::SLLX, 3).addReg(tmpReg).addZImm(32)
.addRegDef(tmpReg));
// Code to set the low 32 bits of the value in register `dest' // Code to set the low 32 bits of the value in register `dest'
CreateSETUWConst(target, C, dest, mvec); CreateSETUWConst(target, C, dest, mvec);
// dest = OR(tmpReg, dest) // dest = OR(tmpReg, dest)
mvec.push_back(BuildMI(OR, 3).addReg(dest).addReg(tmpReg).addRegDef(dest)); mvec.push_back(BuildMI(V9::OR,3).addReg(dest).addReg(tmpReg).addRegDef(dest));
} }
@ -192,17 +193,17 @@ CreateSETXConst(const TargetMachine& target, uint64_t C,
static inline void static inline void
CreateSETUWLabel(const TargetMachine& target, Value* val, CreateSETUWLabel(const TargetMachine& target, Value* val,
Instruction* dest, vector<MachineInstr*>& mvec) Instruction* dest, std::vector<MachineInstr*>& mvec)
{ {
MachineInstr* MI; MachineInstr* MI;
// Set the high 22 bits in dest // Set the high 22 bits in dest
MI = BuildMI(SETHI, 2).addReg(val).addRegDef(dest); MI = BuildMI(V9::SETHI, 2).addReg(val).addRegDef(dest);
MI->setOperandHi32(0); MI->setOperandHi32(0);
mvec.push_back(MI); mvec.push_back(MI);
// Set the low 10 bits in dest // Set the low 10 bits in dest
MI = BuildMI(OR, 3).addReg(dest).addReg(val).addRegDef(dest); MI = BuildMI(V9::OR, 3).addReg(dest).addReg(val).addRegDef(dest);
MI->setOperandLo32(1); MI->setOperandLo32(1);
mvec.push_back(MI); mvec.push_back(MI);
} }
@ -217,30 +218,31 @@ CreateSETUWLabel(const TargetMachine& target, Value* val,
static inline void static inline void
CreateSETXLabel(const TargetMachine& target, CreateSETXLabel(const TargetMachine& target,
Value* val, Instruction* tmpReg, Instruction* dest, Value* val, Instruction* tmpReg, Instruction* dest,
vector<MachineInstr*>& mvec) std::vector<MachineInstr*>& mvec)
{ {
assert(isa<Constant>(val) || isa<GlobalValue>(val) && assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
"I only know about constant values and global addresses"); "I only know about constant values and global addresses");
MachineInstr* MI; MachineInstr* MI;
MI = BuildMI(SETHI, 2).addPCDisp(val).addRegDef(tmpReg); MI = BuildMI(V9::SETHI, 2).addPCDisp(val).addRegDef(tmpReg);
MI->setOperandHi64(0); MI->setOperandHi64(0);
mvec.push_back(MI); mvec.push_back(MI);
MI = BuildMI(OR, 3).addReg(tmpReg).addPCDisp(val).addRegDef(tmpReg); MI = BuildMI(V9::OR, 3).addReg(tmpReg).addPCDisp(val).addRegDef(tmpReg);
MI->setOperandLo64(1); MI->setOperandLo64(1);
mvec.push_back(MI); mvec.push_back(MI);
mvec.push_back(BuildMI(SLLX, 3).addReg(tmpReg).addZImm(32).addRegDef(tmpReg)); mvec.push_back(BuildMI(V9::SLLX, 3).addReg(tmpReg).addZImm(32)
MI = BuildMI(SETHI, 2).addPCDisp(val).addRegDef(dest); .addRegDef(tmpReg));
MI = BuildMI(V9::SETHI, 2).addPCDisp(val).addRegDef(dest);
MI->setOperandHi32(0); MI->setOperandHi32(0);
mvec.push_back(MI); mvec.push_back(MI);
MI = BuildMI(OR, 3).addReg(dest).addReg(tmpReg).addRegDef(dest); MI = BuildMI(V9::OR, 3).addReg(dest).addReg(tmpReg).addRegDef(dest);
mvec.push_back(MI); mvec.push_back(MI);
MI = BuildMI(OR, 3).addReg(dest).addPCDisp(val).addRegDef(dest); MI = BuildMI(V9::OR, 3).addReg(dest).addPCDisp(val).addRegDef(dest);
MI->setOperandLo32(1); MI->setOperandLo32(1);
mvec.push_back(MI); mvec.push_back(MI);
} }
@ -303,7 +305,7 @@ CreateIntSetInstruction(const TargetMachine& target,
// Entry == 0 ==> no immediate constant field exists at all. // Entry == 0 ==> no immediate constant field exists at all.
// Entry > 0 ==> abs(immediate constant) <= Entry // Entry > 0 ==> abs(immediate constant) <= Entry
// //
vector<int> MaxConstantsTable(Instruction::OtherOpsEnd); std::vector<int> MaxConstantsTable(Instruction::OtherOpsEnd);
static int static int
MaxConstantForInstr(unsigned llvmOpCode) MaxConstantForInstr(unsigned llvmOpCode)
@ -312,20 +314,20 @@ MaxConstantForInstr(unsigned llvmOpCode)
if (llvmOpCode >= Instruction::BinaryOpsBegin && if (llvmOpCode >= Instruction::BinaryOpsBegin &&
llvmOpCode < Instruction::BinaryOpsEnd) llvmOpCode < Instruction::BinaryOpsEnd)
modelOpCode = ADD; modelOpCode = V9::ADD;
else else
switch(llvmOpCode) { switch(llvmOpCode) {
case Instruction::Ret: modelOpCode = JMPLCALL; break; case Instruction::Ret: modelOpCode = V9::JMPLCALL; break;
case Instruction::Malloc: case Instruction::Malloc:
case Instruction::Alloca: case Instruction::Alloca:
case Instruction::GetElementPtr: case Instruction::GetElementPtr:
case Instruction::PHINode: case Instruction::PHINode:
case Instruction::Cast: case Instruction::Cast:
case Instruction::Call: modelOpCode = ADD; break; case Instruction::Call: modelOpCode = V9::ADD; break;
case Instruction::Shl: case Instruction::Shl:
case Instruction::Shr: modelOpCode = SLLX; break; case Instruction::Shr: modelOpCode = V9::SLLX; break;
default: break; default: break;
}; };
@ -363,8 +365,8 @@ InitializeMaxConstantsTable()
/*ctor*/ /*ctor*/
UltraSparcInstrInfo::UltraSparcInstrInfo() UltraSparcInstrInfo::UltraSparcInstrInfo()
: TargetInstrInfo(SparcMachineInstrDesc, : TargetInstrInfo(SparcMachineInstrDesc,
/*descSize = */ NUM_TOTAL_OPCODES, /*descSize = */ V9::NUM_TOTAL_OPCODES,
/*numRealOpCodes = */ NUM_REAL_OPCODES) /*numRealOpCodes = */ V9::NUM_REAL_OPCODES)
{ {
InitializeMaxConstantsTable(); InitializeMaxConstantsTable();
} }
@ -405,7 +407,7 @@ UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
Function* F, Function* F,
Value* val, Value* val,
Instruction* dest, Instruction* dest,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
assert(isa<Constant>(val) || isa<GlobalValue>(val) && assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
@ -512,7 +514,7 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
Function* F, Function* F,
Value* val, Value* val,
Instruction* dest, Instruction* dest,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
assert((val->getType()->isIntegral() || isa<PointerType>(val->getType())) assert((val->getType()->isIntegral() || isa<PointerType>(val->getType()))
@ -569,7 +571,7 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
Function* F, Function* F,
Value* val, Value* val,
Instruction* dest, Instruction* dest,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
const Type* opTy = val->getType(); const Type* opTy = val->getType();
@ -612,7 +614,7 @@ UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
Function *F, Function *F,
Value* src, Value* src,
Instruction* dest, Instruction* dest,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
bool loadConstantToReg = false; bool loadConstantToReg = false;
@ -620,47 +622,47 @@ UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
const Type* resultType = dest->getType(); const Type* resultType = dest->getType();
MachineOpCode opCode = ChooseAddInstructionByType(resultType); MachineOpCode opCode = ChooseAddInstructionByType(resultType);
if (opCode == INVALID_OPCODE) if (opCode == V9::INVALID_OPCODE)
{ {
assert(0 && "Unsupported result type in CreateCopyInstructionsByType()"); assert(0 && "Unsupported result type in CreateCopyInstructionsByType()");
return; return;
} }
// if `src' is a constant that doesn't fit in the immed field or if it is // if `src' is a constant that doesn't fit in the immed field or if it is
// a global variable (i.e., a constant address), generate a load // a global variable (i.e., a constant address), generate a load
// instruction instead of an add // instruction instead of an add
// //
if (isa<Constant>(src)) if (isa<Constant>(src))
{ {
unsigned int machineRegNum; unsigned int machineRegNum;
int64_t immedValue; int64_t immedValue;
MachineOperand::MachineOperandType opType = MachineOperand::MachineOperandType opType =
ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true, ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true,
machineRegNum, immedValue); machineRegNum, immedValue);
if (opType == MachineOperand::MO_VirtualRegister) if (opType == MachineOperand::MO_VirtualRegister)
loadConstantToReg = true; loadConstantToReg = true;
} }
else if (isa<GlobalValue>(src)) else if (isa<GlobalValue>(src))
loadConstantToReg = true; loadConstantToReg = true;
if (loadConstantToReg) if (loadConstantToReg)
{ // `src' is constant and cannot fit in immed field for the ADD { // `src' is constant and cannot fit in immed field for the ADD
// Insert instructions to "load" the constant into a register // Insert instructions to "load" the constant into a register
target.getInstrInfo().CreateCodeToLoadConst(target, F, src, dest, target.getInstrInfo().CreateCodeToLoadConst(target, F, src, dest,
mvec, mcfi); mvec, mcfi);
} }
else else
{ // Create an add-with-0 instruction of the appropriate type. { // Create an add-with-0 instruction of the appropriate type.
// Make `src' the second operand, in case it is a constant // Make `src' the second operand, in case it is a constant
// Use (unsigned long) 0 for a NULL pointer value. // Use (unsigned long) 0 for a NULL pointer value.
// //
const Type* Ty =isa<PointerType>(resultType) ? Type::ULongTy : resultType; const Type* Ty =isa<PointerType>(resultType) ? Type::ULongTy : resultType;
MachineInstr* MI = MachineInstr* MI =
BuildMI(opCode, 3).addReg(Constant::getNullValue(Ty)) BuildMI(opCode, 3).addReg(Constant::getNullValue(Ty))
.addReg(src).addRegDef(dest); .addReg(src).addRegDef(dest);
mvec.push_back(MI); mvec.push_back(MI);
} }
} }
@ -673,7 +675,7 @@ CreateBitExtensionInstructions(bool signExtend,
Value* srcVal, Value* srcVal,
Value* destVal, Value* destVal,
unsigned int numLowBits, unsigned int numLowBits,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) MachineCodeForInstruction& mcfi)
{ {
MachineInstr* M; MachineInstr* M;
@ -681,17 +683,17 @@ CreateBitExtensionInstructions(bool signExtend,
assert(numLowBits <= 32 && "Otherwise, nothing should be done here!"); assert(numLowBits <= 32 && "Otherwise, nothing should be done here!");
if (numLowBits < 32) if (numLowBits < 32)
{ // SLL is needed since operand size is < 32 bits. { // SLL is needed since operand size is < 32 bits.
TmpInstruction *tmpI = new TmpInstruction(destVal->getType(), TmpInstruction *tmpI = new TmpInstruction(destVal->getType(),
srcVal, destVal, "make32"); srcVal, destVal, "make32");
mcfi.addTemp(tmpI); mcfi.addTemp(tmpI);
mvec.push_back(BuildMI(SLLX, 3).addReg(srcVal).addZImm(32-numLowBits) mvec.push_back(BuildMI(V9::SLLX, 3).addReg(srcVal)
.addRegDef(tmpI)); .addZImm(32-numLowBits).addRegDef(tmpI));
srcVal = tmpI; srcVal = tmpI;
} }
mvec.push_back(BuildMI(signExtend? SRA : SRL, 3).addReg(srcVal) mvec.push_back(BuildMI(signExtend? V9::SRA : V9::SRL, 3)
.addZImm(32-numLowBits).addRegDef(destVal)); .addReg(srcVal).addZImm(32-numLowBits).addRegDef(destVal));
} }
@ -708,7 +710,7 @@ UltraSparcInstrInfo::CreateSignExtensionInstructions(
Value* srcVal, Value* srcVal,
Value* destVal, Value* destVal,
unsigned int numLowBits, unsigned int numLowBits,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
CreateBitExtensionInstructions(/*signExtend*/ true, target, F, srcVal, CreateBitExtensionInstructions(/*signExtend*/ true, target, F, srcVal,
@ -730,7 +732,7 @@ UltraSparcInstrInfo::CreateZeroExtensionInstructions(
Value* srcVal, Value* srcVal,
Value* destVal, Value* destVal,
unsigned int numLowBits, unsigned int numLowBits,
vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const MachineCodeForInstruction& mcfi) const
{ {
CreateBitExtensionInstructions(/*signExtend*/ false, target, F, srcVal, CreateBitExtensionInstructions(/*signExtend*/ false, target, F, srcVal,

View File

@ -270,15 +270,15 @@ ChooseBprInstruction(const InstructionNode* instrNode)
switch(setCCInstr->getOpcode()) switch(setCCInstr->getOpcode())
{ {
case Instruction::SetEQ: opCode = BRZ; break; case Instruction::SetEQ: opCode = V9::BRZ; break;
case Instruction::SetNE: opCode = BRNZ; break; case Instruction::SetNE: opCode = V9::BRNZ; break;
case Instruction::SetLE: opCode = BRLEZ; break; case Instruction::SetLE: opCode = V9::BRLEZ; break;
case Instruction::SetGE: opCode = BRGEZ; break; case Instruction::SetGE: opCode = V9::BRGEZ; break;
case Instruction::SetLT: opCode = BRLZ; break; case Instruction::SetLT: opCode = V9::BRLZ; break;
case Instruction::SetGT: opCode = BRGZ; break; case Instruction::SetGT: opCode = V9::BRGZ; break;
default: default:
assert(0 && "Unrecognized VM instruction!"); assert(0 && "Unrecognized VM instruction!");
opCode = INVALID_OPCODE; opCode = V9::INVALID_OPCODE;
break; break;
} }
@ -290,7 +290,7 @@ static inline MachineOpCode
ChooseBpccInstruction(const InstructionNode* instrNode, ChooseBpccInstruction(const InstructionNode* instrNode,
const BinaryOperator* setCCInstr) const BinaryOperator* setCCInstr)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned(); bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned();
@ -298,12 +298,12 @@ ChooseBpccInstruction(const InstructionNode* instrNode,
{ {
switch(setCCInstr->getOpcode()) switch(setCCInstr->getOpcode())
{ {
case Instruction::SetEQ: opCode = BE; break; case Instruction::SetEQ: opCode = V9::BE; break;
case Instruction::SetNE: opCode = BNE; break; case Instruction::SetNE: opCode = V9::BNE; break;
case Instruction::SetLE: opCode = BLE; break; case Instruction::SetLE: opCode = V9::BLE; break;
case Instruction::SetGE: opCode = BGE; break; case Instruction::SetGE: opCode = V9::BGE; break;
case Instruction::SetLT: opCode = BL; break; case Instruction::SetLT: opCode = V9::BL; break;
case Instruction::SetGT: opCode = BG; break; case Instruction::SetGT: opCode = V9::BG; break;
default: default:
assert(0 && "Unrecognized VM instruction!"); assert(0 && "Unrecognized VM instruction!");
break; break;
@ -313,12 +313,12 @@ ChooseBpccInstruction(const InstructionNode* instrNode,
{ {
switch(setCCInstr->getOpcode()) switch(setCCInstr->getOpcode())
{ {
case Instruction::SetEQ: opCode = BE; break; case Instruction::SetEQ: opCode = V9::BE; break;
case Instruction::SetNE: opCode = BNE; break; case Instruction::SetNE: opCode = V9::BNE; break;
case Instruction::SetLE: opCode = BLEU; break; case Instruction::SetLE: opCode = V9::BLEU; break;
case Instruction::SetGE: opCode = BCC; break; case Instruction::SetGE: opCode = V9::BCC; break;
case Instruction::SetLT: opCode = BCS; break; case Instruction::SetLT: opCode = V9::BCS; break;
case Instruction::SetGT: opCode = BGU; break; case Instruction::SetGT: opCode = V9::BGU; break;
default: default:
assert(0 && "Unrecognized VM instruction!"); assert(0 && "Unrecognized VM instruction!");
break; break;
@ -332,16 +332,16 @@ static inline MachineOpCode
ChooseBFpccInstruction(const InstructionNode* instrNode, ChooseBFpccInstruction(const InstructionNode* instrNode,
const BinaryOperator* setCCInstr) const BinaryOperator* setCCInstr)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
switch(setCCInstr->getOpcode()) switch(setCCInstr->getOpcode())
{ {
case Instruction::SetEQ: opCode = FBE; break; case Instruction::SetEQ: opCode = V9::FBE; break;
case Instruction::SetNE: opCode = FBNE; break; case Instruction::SetNE: opCode = V9::FBNE; break;
case Instruction::SetLE: opCode = FBLE; break; case Instruction::SetLE: opCode = V9::FBLE; break;
case Instruction::SetGE: opCode = FBGE; break; case Instruction::SetGE: opCode = V9::FBGE; break;
case Instruction::SetLT: opCode = FBL; break; case Instruction::SetLT: opCode = V9::FBL; break;
case Instruction::SetGT: opCode = FBG; break; case Instruction::SetGT: opCode = V9::FBG; break;
default: default:
assert(0 && "Unrecognized VM instruction!"); assert(0 && "Unrecognized VM instruction!");
break; break;
@ -405,16 +405,16 @@ ChooseBccInstruction(const InstructionNode* instrNode,
static inline MachineOpCode static inline MachineOpCode
ChooseMovFpccInstruction(const InstructionNode* instrNode) ChooseMovFpccInstruction(const InstructionNode* instrNode)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
switch(instrNode->getInstruction()->getOpcode()) switch(instrNode->getInstruction()->getOpcode())
{ {
case Instruction::SetEQ: opCode = MOVFE; break; case Instruction::SetEQ: opCode = V9::MOVFE; break;
case Instruction::SetNE: opCode = MOVFNE; break; case Instruction::SetNE: opCode = V9::MOVFNE; break;
case Instruction::SetLE: opCode = MOVFLE; break; case Instruction::SetLE: opCode = V9::MOVFLE; break;
case Instruction::SetGE: opCode = MOVFGE; break; case Instruction::SetGE: opCode = V9::MOVFGE; break;
case Instruction::SetLT: opCode = MOVFL; break; case Instruction::SetLT: opCode = V9::MOVFL; break;
case Instruction::SetGT: opCode = MOVFG; break; case Instruction::SetGT: opCode = V9::MOVFG; break;
default: default:
assert(0 && "Unrecognized VM instruction!"); assert(0 && "Unrecognized VM instruction!");
break; break;
@ -437,17 +437,17 @@ ChooseMovpccAfterSub(const InstructionNode* instrNode,
bool& mustClearReg, bool& mustClearReg,
int& valueToMove) int& valueToMove)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
mustClearReg = true; mustClearReg = true;
valueToMove = 1; valueToMove = 1;
switch(instrNode->getInstruction()->getOpcode()) switch(instrNode->getInstruction()->getOpcode())
{ {
case Instruction::SetEQ: opCode = MOVE; break; case Instruction::SetEQ: opCode = V9::MOVE; break;
case Instruction::SetLE: opCode = MOVLE; break; case Instruction::SetLE: opCode = V9::MOVLE; break;
case Instruction::SetGE: opCode = MOVGE; break; case Instruction::SetGE: opCode = V9::MOVGE; break;
case Instruction::SetLT: opCode = MOVL; break; case Instruction::SetLT: opCode = V9::MOVL; break;
case Instruction::SetGT: opCode = MOVG; break; case Instruction::SetGT: opCode = V9::MOVG; break;
case Instruction::SetNE: assert(0 && "No move required!"); break; case Instruction::SetNE: assert(0 && "No move required!"); break;
default: assert(0 && "Unrecognized VM instr!"); break; default: assert(0 && "Unrecognized VM instr!"); break;
} }
@ -458,17 +458,17 @@ ChooseMovpccAfterSub(const InstructionNode* instrNode,
static inline MachineOpCode static inline MachineOpCode
ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType) ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
switch(vopCode) switch(vopCode)
{ {
case ToFloatTy: case ToFloatTy:
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy) if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
opCode = FITOS; opCode = V9::FITOS;
else if (opType == Type::LongTy) else if (opType == Type::LongTy)
opCode = FXTOS; opCode = V9::FXTOS;
else if (opType == Type::DoubleTy) else if (opType == Type::DoubleTy)
opCode = FDTOS; opCode = V9::FDTOS;
else if (opType == Type::FloatTy) else if (opType == Type::FloatTy)
; ;
else else
@ -482,11 +482,11 @@ ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
if (opType == Type::SByteTy || opType == Type::UByteTy || if (opType == Type::SByteTy || opType == Type::UByteTy ||
opType == Type::ShortTy || opType == Type::UShortTy || opType == Type::ShortTy || opType == Type::UShortTy ||
opType == Type::IntTy || opType == Type::UIntTy) opType == Type::IntTy || opType == Type::UIntTy)
opCode = FITOD; opCode = V9::FITOD;
else if (opType == Type::LongTy || opType == Type::ULongTy) else if (opType == Type::LongTy || opType == Type::ULongTy)
opCode = FXTOD; opCode = V9::FXTOD;
else if (opType == Type::FloatTy) else if (opType == Type::FloatTy)
opCode = FSTOD; opCode = V9::FSTOD;
else if (opType == Type::DoubleTy) else if (opType == Type::DoubleTy)
; ;
else else
@ -503,7 +503,7 @@ ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
static inline MachineOpCode static inline MachineOpCode
ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType) ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType)
{ {
MachineOpCode opCode = INVALID_OPCODE;; MachineOpCode opCode = V9::INVALID_OPCODE;;
assert((opType == Type::FloatTy || opType == Type::DoubleTy) assert((opType == Type::FloatTy || opType == Type::DoubleTy)
&& "This function should only be called for FLOAT or DOUBLE"); && "This function should only be called for FLOAT or DOUBLE");
@ -516,11 +516,11 @@ ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType)
else if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID || else if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID ||
tid==Type::UByteTyID || tid==Type::UShortTyID) tid==Type::UByteTyID || tid==Type::UShortTyID)
{ {
opCode = (opType == Type::FloatTy)? FSTOI : FDTOI; opCode = (opType == Type::FloatTy)? V9::FSTOI : V9::FDTOI;
} }
else if (tid==Type::LongTyID || tid==Type::ULongTyID) else if (tid==Type::LongTyID || tid==Type::ULongTyID)
{ {
opCode = (opType == Type::FloatTy)? FSTOX : FDTOX; opCode = (opType == Type::FloatTy)? V9::FSTOX : V9::FDTOX;
} }
else else
assert(0 && "Should not get here, Mo!"); assert(0 && "Should not get here, Mo!");
@ -533,7 +533,7 @@ CreateConvertFPToIntInstr(Type::PrimitiveID destTID,
Value* srcVal, Value* destVal) Value* srcVal, Value* destVal)
{ {
MachineOpCode opCode = ChooseConvertFPToIntInstr(destTID, srcVal->getType()); MachineOpCode opCode = ChooseConvertFPToIntInstr(destTID, srcVal->getType());
assert(opCode != INVALID_OPCODE && "Expected to need conversion!"); assert(opCode != V9::INVALID_OPCODE && "Expected to need conversion!");
return BuildMI(opCode, 2).addReg(srcVal).addRegDef(destVal); return BuildMI(opCode, 2).addReg(srcVal).addRegDef(destVal);
} }
@ -594,7 +594,7 @@ static inline MachineInstr*
CreateMovFloatInstruction(const InstructionNode* instrNode, CreateMovFloatInstruction(const InstructionNode* instrNode,
const Type* resultType) const Type* resultType)
{ {
return BuildMI((resultType == Type::FloatTy) ? FMOVS : FMOVD, 2) return BuildMI((resultType == Type::FloatTy) ? V9::FMOVS : V9::FMOVD, 2)
.addReg(instrNode->leftChild()->getValue()) .addReg(instrNode->leftChild()->getValue())
.addRegDef(instrNode->getValue()); .addRegDef(instrNode->getValue());
} }
@ -625,17 +625,17 @@ CreateAddConstInstruction(const InstructionNode* instrNode)
static inline MachineOpCode static inline MachineOpCode
ChooseSubInstructionByType(const Type* resultType) ChooseSubInstructionByType(const Type* resultType)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
if (resultType->isInteger() || isa<PointerType>(resultType)) if (resultType->isInteger() || isa<PointerType>(resultType))
{ {
opCode = SUB; opCode = V9::SUB;
} }
else else
switch(resultType->getPrimitiveID()) switch(resultType->getPrimitiveID())
{ {
case Type::FloatTyID: opCode = FSUBS; break; case Type::FloatTyID: opCode = V9::FSUBS; break;
case Type::DoubleTyID: opCode = FSUBD; break; case Type::DoubleTyID: opCode = V9::FSUBD; break;
default: assert(0 && "Invalid type for SUB instruction"); break; default: assert(0 && "Invalid type for SUB instruction"); break;
} }
@ -669,12 +669,12 @@ CreateSubConstInstruction(const InstructionNode* instrNode)
static inline MachineOpCode static inline MachineOpCode
ChooseFcmpInstruction(const InstructionNode* instrNode) ChooseFcmpInstruction(const InstructionNode* instrNode)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue(); Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
switch(operand->getType()->getPrimitiveID()) { switch(operand->getType()->getPrimitiveID()) {
case Type::FloatTyID: opCode = FCMPS; break; case Type::FloatTyID: opCode = V9::FCMPS; break;
case Type::DoubleTyID: opCode = FCMPD; break; case Type::DoubleTyID: opCode = V9::FCMPD; break;
default: assert(0 && "Invalid type for FCMP instruction"); break; default: assert(0 && "Invalid type for FCMP instruction"); break;
} }
@ -703,15 +703,15 @@ BothFloatToDouble(const InstructionNode* instrNode)
static inline MachineOpCode static inline MachineOpCode
ChooseMulInstructionByType(const Type* resultType) ChooseMulInstructionByType(const Type* resultType)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
if (resultType->isInteger()) if (resultType->isInteger())
opCode = MULX; opCode = V9::MULX;
else else
switch(resultType->getPrimitiveID()) switch(resultType->getPrimitiveID())
{ {
case Type::FloatTyID: opCode = FMULS; break; case Type::FloatTyID: opCode = V9::FMULS; break;
case Type::DoubleTyID: opCode = FMULD; break; case Type::DoubleTyID: opCode = V9::FMULD; break;
default: assert(0 && "Invalid type for MUL instruction"); break; default: assert(0 && "Invalid type for MUL instruction"); break;
} }
@ -724,8 +724,8 @@ static inline MachineInstr*
CreateIntNegInstruction(const TargetMachine& target, CreateIntNegInstruction(const TargetMachine& target,
Value* vreg) Value* vreg)
{ {
return BuildMI(SUB, 3).addMReg(target.getRegInfo().getZeroRegNum()) return BuildMI(V9::SUB, 3).addMReg(target.getRegInfo().getZeroRegNum())
.addReg(vreg).addRegDef(vreg); .addReg(vreg).addRegDef(vreg);
} }
@ -758,7 +758,7 @@ CreateShiftInstructions(const TargetMachine& target,
// //
Value* shiftDest = destVal; Value* shiftDest = destVal;
unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType()); unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType());
if ((shiftOpCode == SLL || shiftOpCode == SLLX) && opSize < 8) if ((shiftOpCode == V9::SLL || shiftOpCode == V9::SLLX) && opSize < 8)
{ // put SLL result into a temporary { // put SLL result into a temporary
shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp"); shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp");
mcfi.addTemp(shiftDest); mcfi.addTemp(shiftDest);
@ -792,7 +792,7 @@ CreateMulConstInstruction(const TargetMachine &target, Function* F,
MachineCodeForInstruction& mcfi) MachineCodeForInstruction& mcfi)
{ {
/* Use max. multiply cost, viz., cost of MULX */ /* Use max. multiply cost, viz., cost of MULX */
unsigned cost = target.getInstrInfo().minLatency(MULX); unsigned cost = target.getInstrInfo().minLatency(V9::MULX);
unsigned firstNewInstr = mvec.size(); unsigned firstNewInstr = mvec.size();
Value* constOp = rval; Value* constOp = rval;
@ -805,66 +805,57 @@ CreateMulConstInstruction(const TargetMachine &target, Function* F,
// //
const Type* resultType = destVal->getType(); const Type* resultType = destVal->getType();
if (resultType->isInteger() || isa<PointerType>(resultType)) if (resultType->isInteger() || isa<PointerType>(resultType)) {
{ bool isValidConst;
bool isValidConst; int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst); if (isValidConst) {
if (isValidConst) unsigned pow;
{ bool needNeg = false;
unsigned pow; if (C < 0) {
bool needNeg = false; needNeg = true;
if (C < 0) C = -C;
{ }
needNeg = true;
C = -C;
}
if (C == 0 || C == 1) { if (C == 0 || C == 1) {
cost = target.getInstrInfo().minLatency(ADD); cost = target.getInstrInfo().minLatency(V9::ADD);
unsigned Zero = target.getRegInfo().getZeroRegNum(); unsigned Zero = target.getRegInfo().getZeroRegNum();
MachineInstr* M; MachineInstr* M;
if (C == 0) if (C == 0)
M = BuildMI(ADD,3).addMReg(Zero).addMReg(Zero).addRegDef(destVal); M = BuildMI(V9::ADD,3).addMReg(Zero).addMReg(Zero).addRegDef(destVal);
else else
M = BuildMI(ADD,3).addReg(lval).addMReg(Zero).addRegDef(destVal); M = BuildMI(V9::ADD,3).addReg(lval).addMReg(Zero).addRegDef(destVal);
mvec.push_back(M); mvec.push_back(M);
} }
else if (isPowerOf2(C, pow)) else if (isPowerOf2(C, pow)) {
{ unsigned opSize = target.getTargetData().getTypeSize(resultType);
unsigned opSize = target.getTargetData().getTypeSize(resultType); MachineOpCode opCode = (opSize <= 32)? V9::SLL : V9::SLLX;
MachineOpCode opCode = (opSize <= 32)? SLL : SLLX; CreateShiftInstructions(target, F, opCode, lval, NULL, pow,
CreateShiftInstructions(target, F, opCode, lval, NULL, pow, destVal, mvec, mcfi);
destVal, mvec, mcfi); }
}
if (mvec.size() > 0 && needNeg) if (mvec.size() > 0 && needNeg)
{ // insert <reg = SUB 0, reg> after the instr to flip the sign { // insert <reg = SUB 0, reg> after the instr to flip the sign
MachineInstr* M = CreateIntNegInstruction(target, destVal); MachineInstr* M = CreateIntNegInstruction(target, destVal);
mvec.push_back(M); mvec.push_back(M);
} }
}
} }
else } else {
{ if (ConstantFP *FPC = dyn_cast<ConstantFP>(constOp)) {
if (ConstantFP *FPC = dyn_cast<ConstantFP>(constOp)) double dval = FPC->getValue();
{ if (fabs(dval) == 1) {
double dval = FPC->getValue(); MachineOpCode opCode = (dval < 0)
if (fabs(dval) == 1) ? (resultType == Type::FloatTy? V9::FNEGS : V9::FNEGD)
{ : (resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD);
MachineOpCode opCode = (dval < 0) mvec.push_back(BuildMI(opCode,2).addReg(lval).addRegDef(destVal));
? (resultType == Type::FloatTy? FNEGS : FNEGD) }
: (resultType == Type::FloatTy? FMOVS : FMOVD);
mvec.push_back(BuildMI(opCode,2).addReg(lval).addRegDef(destVal));
}
}
} }
}
if (firstNewInstr < mvec.size()) if (firstNewInstr < mvec.size()) {
{ cost = 0;
cost = 0; for (unsigned i=firstNewInstr; i < mvec.size(); ++i)
for (unsigned i=firstNewInstr; i < mvec.size(); ++i) cost += target.getInstrInfo().minLatency(mvec[i]->getOpCode());
cost += target.getInstrInfo().minLatency(mvec[i]->getOpCode()); }
}
return cost; return cost;
} }
@ -907,16 +898,16 @@ CreateMulInstruction(const TargetMachine &target, Function* F,
{ {
unsigned L = mvec.size(); unsigned L = mvec.size();
CreateCheapestMulConstInstruction(target,F, lval, rval, destVal, mvec, mcfi); CreateCheapestMulConstInstruction(target,F, lval, rval, destVal, mvec, mcfi);
if (mvec.size() == L) if (mvec.size() == L) {
{ // no instructions were added so create MUL reg, reg, reg. // no instructions were added so create MUL reg, reg, reg.
// Use FSMULD if both operands are actually floats cast to doubles. // Use FSMULD if both operands are actually floats cast to doubles.
// Otherwise, use the default opcode for the appropriate type. // Otherwise, use the default opcode for the appropriate type.
MachineOpCode mulOp = ((forceMulOp != INVALID_MACHINE_OPCODE) MachineOpCode mulOp = ((forceMulOp != INVALID_MACHINE_OPCODE)
? forceMulOp ? forceMulOp
: ChooseMulInstructionByType(destVal->getType())); : ChooseMulInstructionByType(destVal->getType()));
mvec.push_back(BuildMI(mulOp, 3).addReg(lval).addReg(rval) mvec.push_back(BuildMI(mulOp, 3).addReg(lval).addReg(rval)
.addRegDef(destVal)); .addRegDef(destVal));
} }
} }
@ -928,17 +919,17 @@ static inline MachineOpCode
ChooseDivInstruction(TargetMachine &target, ChooseDivInstruction(TargetMachine &target,
const InstructionNode* instrNode) const InstructionNode* instrNode)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
const Type* resultType = instrNode->getInstruction()->getType(); const Type* resultType = instrNode->getInstruction()->getType();
if (resultType->isInteger()) if (resultType->isInteger())
opCode = resultType->isSigned()? SDIVX : UDIVX; opCode = resultType->isSigned()? V9::SDIVX : V9::UDIVX;
else else
switch(resultType->getPrimitiveID()) switch(resultType->getPrimitiveID())
{ {
case Type::FloatTyID: opCode = FDIVS; break; case Type::FloatTyID: opCode = V9::FDIVS; break;
case Type::DoubleTyID: opCode = FDIVD; break; case Type::DoubleTyID: opCode = V9::FDIVD; break;
default: assert(0 && "Invalid type for DIV instruction"); break; default: assert(0 && "Invalid type for DIV instruction"); break;
} }
@ -967,50 +958,45 @@ CreateDivConstInstruction(TargetMachine &target,
const Type* resultType = instrNode->getInstruction()->getType(); const Type* resultType = instrNode->getInstruction()->getType();
if (resultType->isInteger()) if (resultType->isInteger())
{ {
unsigned pow; unsigned pow;
bool isValidConst; bool isValidConst;
int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst); int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
if (isValidConst) if (isValidConst) {
{ bool needNeg = false;
bool needNeg = false; if (C < 0) {
if (C < 0) { needNeg = true;
needNeg = true; C = -C;
C = -C; }
}
if (C == 1) { if (C == 1) {
mvec.push_back(BuildMI(ADD, 3).addReg(LHS).addMReg(ZeroReg) mvec.push_back(BuildMI(V9::ADD, 3).addReg(LHS).addMReg(ZeroReg)
.addRegDef(DestVal)); .addRegDef(DestVal));
} else if (isPowerOf2(C, pow)) { } else if (isPowerOf2(C, pow)) {
unsigned opCode= ((resultType->isSigned()) unsigned opCode= ((resultType->isSigned())
? (resultType==Type::LongTy) ? SRAX : SRA ? (resultType==Type::LongTy) ? V9::SRAX : V9::SRA
: (resultType==Type::LongTy) ? SRLX : SRL); : (resultType==Type::LongTy) ? V9::SRLX : V9::SRL);
mvec.push_back(BuildMI(opCode, 3).addReg(LHS).addZImm(pow) mvec.push_back(BuildMI(opCode, 3).addReg(LHS).addZImm(pow)
.addRegDef(DestVal)); .addRegDef(DestVal));
} }
if (needNeg && (C == 1 || isPowerOf2(C, pow))) if (needNeg && (C == 1 || isPowerOf2(C, pow))) {
{ // insert <reg = SUB 0, reg> after the instr to flip the sign // insert <reg = SUB 0, reg> after the instr to flip the sign
mvec.push_back(CreateIntNegInstruction(target, DestVal)); mvec.push_back(CreateIntNegInstruction(target, DestVal));
} }
}
} }
else } else {
{ if (ConstantFP *FPC = dyn_cast<ConstantFP>(constOp)) {
if (ConstantFP *FPC = dyn_cast<ConstantFP>(constOp)) double dval = FPC->getValue();
{ if (fabs(dval) == 1) {
double dval = FPC->getValue(); unsigned opCode =
if (fabs(dval) == 1) (dval < 0) ? (resultType == Type::FloatTy? V9::FNEGS : V9::FNEGD)
{ : (resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD);
unsigned opCode =
(dval < 0) ? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
mvec.push_back(BuildMI(opCode, 2).addReg(LHS).addRegDef(DestVal)); mvec.push_back(BuildMI(opCode, 2).addReg(LHS).addRegDef(DestVal));
} }
}
} }
}
} }
@ -1076,12 +1062,12 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
unsigned SPReg = target.getRegInfo().getStackPointer(); unsigned SPReg = target.getRegInfo().getStackPointer();
// Instruction 2: sub %sp, totalSizeVal -> %sp // Instruction 2: sub %sp, totalSizeVal -> %sp
getMvec.push_back(BuildMI(SUB, 3).addMReg(SPReg).addReg(totalSizeVal) getMvec.push_back(BuildMI(V9::SUB, 3).addMReg(SPReg).addReg(totalSizeVal)
.addMReg(SPReg,MOTy::Def)); .addMReg(SPReg,MOTy::Def));
// Instruction 3: add %sp, frameSizeBelowDynamicArea -> result // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
getMvec.push_back(BuildMI(ADD, 3).addMReg(SPReg).addReg(dynamicAreaOffset) getMvec.push_back(BuildMI(V9::ADD, 3).addMReg(SPReg).addReg(dynamicAreaOffset)
.addRegDef(result)); .addRegDef(result));
} }
@ -1106,7 +1092,7 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
int offsetFromFP = mcInfo.getInfo()->computeOffsetforLocalVar(result, int offsetFromFP = mcInfo.getInfo()->computeOffsetforLocalVar(result,
paddedSizeIgnored, paddedSizeIgnored,
tsize * numElements); tsize * numElements);
if (! target.getInstrInfo().constantFitsInImmedField(LDX, offsetFromFP)) { if (! target.getInstrInfo().constantFitsInImmedField(V9::LDX, offsetFromFP)) {
CreateCodeForVariableSizeAlloca(target, result, tsize, CreateCodeForVariableSizeAlloca(target, result, tsize,
ConstantSInt::get(Type::IntTy,numElements), ConstantSInt::get(Type::IntTy,numElements),
getMvec); getMvec);
@ -1122,8 +1108,8 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
// Instruction 1: add %fp, offsetFromFP -> result // Instruction 1: add %fp, offsetFromFP -> result
unsigned FPReg = target.getRegInfo().getFramePointer(); unsigned FPReg = target.getRegInfo().getFramePointer();
getMvec.push_back(BuildMI(ADD, 3).addMReg(FPReg).addReg(offsetVal) getMvec.push_back(BuildMI(V9::ADD, 3).addMReg(FPReg).addReg(offsetVal)
.addRegDef(result)); .addRegDef(result));
} }
@ -1430,14 +1416,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
Instruction* returnReg = new TmpInstruction(returnInstr); Instruction* returnReg = new TmpInstruction(returnInstr);
MachineCodeForInstruction::get(returnInstr).addTemp(returnReg); MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
M = BuildMI(JMPLRET, 3).addReg(returnReg).addSImm(8) M = BuildMI(V9::JMPLRET, 3).addReg(returnReg).addSImm(8)
.addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def); .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def);
if (returnInstr->getReturnValue() != NULL) if (returnInstr->getReturnValue() != NULL)
M->addImplicitRef(returnInstr->getReturnValue()); M->addImplicitRef(returnInstr->getReturnValue());
mvec.push_back(M); mvec.push_back(M);
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -1452,10 +1438,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 5: // stmt: BrUncond case 5: // stmt: BrUncond
{ {
BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
mvec.push_back(BuildMI(BA, 1).addPCDisp(BI->getSuccessor(0))); mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0)));
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -1492,13 +1478,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
// false branch // false branch
mvec.push_back(BuildMI(BA, 1).addPCDisp(brInst->getSuccessor(1))); mvec.push_back(BuildMI(V9::BA, 1)
.addPCDisp(brInst->getSuccessor(1)));
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
// ELSE FALL THROUGH // ELSE FALL THROUGH
@ -1521,13 +1508,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
// false branch // false branch
mvec.push_back(BuildMI(BA, 1).addPCDisp(brInst->getSuccessor(1))); mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(brInst->getSuccessor(1)));
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -1538,12 +1525,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<Constant>(subtreeRoot->leftChild()->getValue()); cast<Constant>(subtreeRoot->leftChild()->getValue());
unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1; unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1;
M = BuildMI(BA, 1).addPCDisp( M = BuildMI(V9::BA, 1).addPCDisp(
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(dest)); cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(dest));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -1552,18 +1539,18 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// Just use the branch-on-integer-register instruction! // Just use the branch-on-integer-register instruction!
// //
BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
M = BuildMI(BRNZ, 2).addReg(subtreeRoot->leftChild()->getValue()) M = BuildMI(V9::BRNZ, 2).addReg(subtreeRoot->leftChild()->getValue())
.addPCDisp(BI->getSuccessor(0)); .addPCDisp(BI->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
// false branch // false branch
mvec.push_back(BuildMI(BA, 1).addPCDisp(BI->getSuccessor(1))); mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(1)));
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -1581,7 +1568,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
Value* notArg = BinaryOperator::getNotArgument( Value* notArg = BinaryOperator::getNotArgument(
cast<BinaryOperator>(subtreeRoot->getInstruction())); cast<BinaryOperator>(subtreeRoot->getInstruction()));
unsigned ZeroReg = target.getRegInfo().getZeroRegNum(); unsigned ZeroReg = target.getRegInfo().getZeroRegNum();
mvec.push_back(BuildMI(XNOR, 3).addReg(notArg).addMReg(ZeroReg) mvec.push_back(BuildMI(V9::XNOR, 3).addReg(notArg).addMReg(ZeroReg)
.addRegDef(subtreeRoot->getValue())); .addRegDef(subtreeRoot->getValue()));
break; break;
} }
@ -1703,7 +1690,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
const MachineCodeForInstruction& mcfi = const MachineCodeForInstruction& mcfi =
MachineCodeForInstruction::get( MachineCodeForInstruction::get(
cast<InstructionNode>(subtreeRoot->parent())->getInstruction()); cast<InstructionNode>(subtreeRoot->parent())->getInstruction());
if (mcfi.size() == 0 || mcfi.front()->getOpCode() == FSMULD) if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD)
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
} }
@ -1713,7 +1700,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
const Type* opType = leftVal->getType(); const Type* opType = leftVal->getType();
MachineOpCode opCode=ChooseConvertToFloatInstr( MachineOpCode opCode=ChooseConvertToFloatInstr(
subtreeRoot->getOpLabel(), opType); subtreeRoot->getOpLabel(), opType);
if (opCode == INVALID_OPCODE) // no conversion needed if (opCode == V9::INVALID_OPCODE) // no conversion needed
{ {
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
} }
@ -1800,7 +1787,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
? FSMULD ? V9::FSMULD
: INVALID_MACHINE_OPCODE); : INVALID_MACHINE_OPCODE);
Instruction* mulInstr = subtreeRoot->getInstruction(); Instruction* mulInstr = subtreeRoot->getInstruction();
CreateMulInstruction(target, mulInstr->getParent()->getParent(), CreateMulInstruction(target, mulInstr->getParent()->getParent(),
@ -1818,7 +1805,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
? FSMULD ? V9::FSMULD
: INVALID_MACHINE_OPCODE); : INVALID_MACHINE_OPCODE);
Instruction* mulInstr = subtreeRoot->getInstruction(); Instruction* mulInstr = subtreeRoot->getInstruction();
CreateMulInstruction(target, mulInstr->getParent()->getParent(), CreateMulInstruction(target, mulInstr->getParent()->getParent(),
@ -1882,7 +1869,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 238: // bool: And(bool, boolconst) case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg) case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant) case 538: // reg : BAnd(reg, Constant)
Add3OperandInstr(AND, subtreeRoot, mvec); Add3OperandInstr(V9::AND, subtreeRoot, mvec);
break; break;
case 138: // bool: And(bool, not) case 138: // bool: And(bool, not)
@ -1895,7 +1882,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
notNode->markFoldedIntoParent(); notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue(); Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue(); Value *Dest = subtreeRoot->getValue();
mvec.push_back(BuildMI(ANDN, 3).addReg(LHS).addReg(notArg) mvec.push_back(BuildMI(V9::ANDN, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def)); .addReg(Dest, MOTy::Def));
break; break;
} }
@ -1904,7 +1891,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 239: // bool: Or(bool, boolconst) case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg) case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant) case 539: // reg : BOr(reg, Constant)
Add3OperandInstr(OR, subtreeRoot, mvec); Add3OperandInstr(V9::OR, subtreeRoot, mvec);
break; break;
case 139: // bool: Or(bool, not) case 139: // bool: Or(bool, not)
@ -1917,8 +1904,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
notNode->markFoldedIntoParent(); notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue(); Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue(); Value *Dest = subtreeRoot->getValue();
mvec.push_back(BuildMI(ORN, 3).addReg(LHS).addReg(notArg) mvec.push_back(BuildMI(V9::ORN, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def)); .addReg(Dest, MOTy::Def));
break; break;
} }
@ -1926,7 +1913,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 240: // bool: Xor(bool, boolconst) case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg) case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant) case 540: // reg : BXor(reg, Constant)
Add3OperandInstr(XOR, subtreeRoot, mvec); Add3OperandInstr(V9::XOR, subtreeRoot, mvec);
break; break;
case 140: // bool: Xor(bool, not) case 140: // bool: Xor(bool, not)
@ -1939,8 +1926,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
notNode->markFoldedIntoParent(); notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue(); Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue(); Value *Dest = subtreeRoot->getValue();
mvec.push_back(BuildMI(XNOR, 3).addReg(LHS).addReg(notArg) mvec.push_back(BuildMI(V9::XNOR, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def)); .addReg(Dest, MOTy::Def));
break; break;
} }
@ -2006,15 +1993,17 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// result of SUBcc instruction anyway. // result of SUBcc instruction anyway.
// //
if (keepSubVal) { if (keepSubVal) {
M = BuildMI(SUBcc, 4).addReg(subtreeRoot->leftChild()->getValue()) M = BuildMI(V9::SUBcc, 4)
.addReg(subtreeRoot->rightChild()->getValue()) .addReg(subtreeRoot->leftChild()->getValue())
.addRegDef(subtreeRoot->getValue()) .addReg(subtreeRoot->rightChild()->getValue())
.addCCReg(tmpForCC, MOTy::Def); .addRegDef(subtreeRoot->getValue())
.addCCReg(tmpForCC, MOTy::Def);
} else { } else {
M = BuildMI(SUBcc, 4).addReg(subtreeRoot->leftChild()->getValue()) M = BuildMI(V9::SUBcc, 4)
.addReg(subtreeRoot->rightChild()->getValue()) .addReg(subtreeRoot->leftChild()->getValue())
.addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def) .addReg(subtreeRoot->rightChild()->getValue())
.addCCReg(tmpForCC, MOTy::Def); .addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def)
.addCCReg(tmpForCC, MOTy::Def);
} }
mvec.push_back(M); mvec.push_back(M);
@ -2045,7 +2034,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
if (mustClearReg) if (mustClearReg)
{// Unconditionally set register to 0 {// Unconditionally set register to 0
M = BuildMI(SETHI, 2).addZImm(0).addRegDef(setCCInstr); M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr);
mvec.push_back(M); mvec.push_back(M);
} }
@ -2070,7 +2059,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 56: // reg: GetElemPtrIdx(reg,reg) case 56: // reg: GetElemPtrIdx(reg,reg)
// If the GetElemPtr was folded into the user (parent), it will be // If the GetElemPtr was folded into the user (parent), it will be
// caught above. For other cases, we have to compute the address. // caught above. For other cases, we have to compute the address.
SetOperandsForMemInstr(ADD, mvec, subtreeRoot, target); SetOperandsForMemInstr(V9::ADD, mvec, subtreeRoot, target);
break; break;
case 57: // reg: Alloca: Implement as 1 instruction: case 57: // reg: Alloca: Implement as 1 instruction:
@ -2136,10 +2125,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// Use JMPL for indirect calls. // Use JMPL for indirect calls.
// //
if (isa<Function>(callee)) // direct function call if (isa<Function>(callee)) // direct function call
M = BuildMI(CALL, 1).addPCDisp(callee); M = BuildMI(V9::CALL, 1).addPCDisp(callee);
else // indirect function call else // indirect function call
M = BuildMI(JMPLCALL, 3).addReg(callee).addSImm((int64_t)0) M = BuildMI(V9::JMPLCALL, 3).addReg(callee).addSImm((int64_t)0)
.addRegDef(retAddrReg); .addRegDef(retAddrReg);
mvec.push_back(M); mvec.push_back(M);
const FunctionType* funcType = const FunctionType* funcType =
@ -2213,7 +2202,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true); mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
// delay slot // delay slot
mvec.push_back(BuildMI(NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
@ -2228,7 +2217,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
"Shl unsupported for other types"); "Shl unsupported for other types");
CreateShiftInstructions(target, shlInstr->getParent()->getParent(), CreateShiftInstructions(target, shlInstr->getParent()->getParent(),
(opType == Type::LongTy)? SLLX : SLL, (opType == Type::LongTy)? V9::SLLX : V9::SLL,
argVal1, argVal2, 0, shlInstr, mvec, argVal1, argVal2, 0, shlInstr, mvec,
MachineCodeForInstruction::get(shlInstr)); MachineCodeForInstruction::get(shlInstr));
break; break;
@ -2239,8 +2228,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert((opType->isInteger() || isa<PointerType>(opType)) && assert((opType->isInteger() || isa<PointerType>(opType)) &&
"Shr unsupported for other types"); "Shr unsupported for other types");
Add3OperandInstr(opType->isSigned() Add3OperandInstr(opType->isSigned()
? (opType == Type::LongTy ? SRAX : SRA) ? (opType == Type::LongTy ? V9::SRAX : V9::SRA)
: (opType == Type::LongTy ? SRLX : SRL), : (opType == Type::LongTy ? V9::SRLX : V9::SRL),
subtreeRoot, mvec); subtreeRoot, mvec);
break; break;
} }
@ -2300,8 +2289,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
for (unsigned i=0, N=mvec.size(); i < N; ++i) for (unsigned i=0, N=mvec.size(); i < N; ++i)
mvec[i]->substituteValue(dest, tmpI); mvec[i]->substituteValue(dest, tmpI);
M = BuildMI(SRL, 3).addReg(tmpI).addZImm(8*(4-destSize)) M = BuildMI(V9::SRL, 3).addReg(tmpI).addZImm(8*(4-destSize))
.addReg(dest, MOTy::Def); .addReg(dest, MOTy::Def);
mvec.push_back(M); mvec.push_back(M);
} }
else if (destSize < 8) else if (destSize < 8)

View File

@ -14,17 +14,17 @@ ChooseLoadInstruction(const Type *DestTy)
{ {
switch (DestTy->getPrimitiveID()) { switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID: case Type::BoolTyID:
case Type::UByteTyID: return LDUB; case Type::UByteTyID: return V9::LDUB;
case Type::SByteTyID: return LDSB; case Type::SByteTyID: return V9::LDSB;
case Type::UShortTyID: return LDUH; case Type::UShortTyID: return V9::LDUH;
case Type::ShortTyID: return LDSH; case Type::ShortTyID: return V9::LDSH;
case Type::UIntTyID: return LDUW; case Type::UIntTyID: return V9::LDUW;
case Type::IntTyID: return LDSW; case Type::IntTyID: return V9::LDSW;
case Type::PointerTyID: case Type::PointerTyID:
case Type::ULongTyID: case Type::ULongTyID:
case Type::LongTyID: return LDX; case Type::LongTyID: return V9::LDX;
case Type::FloatTyID: return LD; case Type::FloatTyID: return V9::LD;
case Type::DoubleTyID: return LDD; case Type::DoubleTyID: return V9::LDD;
default: assert(0 && "Invalid type for Load instruction"); default: assert(0 && "Invalid type for Load instruction");
} }
@ -37,16 +37,16 @@ ChooseStoreInstruction(const Type *DestTy)
switch (DestTy->getPrimitiveID()) { switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID: case Type::BoolTyID:
case Type::UByteTyID: case Type::UByteTyID:
case Type::SByteTyID: return STB; case Type::SByteTyID: return V9::STB;
case Type::UShortTyID: case Type::UShortTyID:
case Type::ShortTyID: return STH; case Type::ShortTyID: return V9::STH;
case Type::UIntTyID: case Type::UIntTyID:
case Type::IntTyID: return STW; case Type::IntTyID: return V9::STW;
case Type::PointerTyID: case Type::PointerTyID:
case Type::ULongTyID: case Type::ULongTyID:
case Type::LongTyID: return STX; case Type::LongTyID: return V9::STX;
case Type::FloatTyID: return ST; case Type::FloatTyID: return V9::ST;
case Type::DoubleTyID: return STD; case Type::DoubleTyID: return V9::STD;
default: assert(0 && "Invalid type for Store instruction"); default: assert(0 && "Invalid type for Store instruction");
} }
@ -57,22 +57,22 @@ ChooseStoreInstruction(const Type *DestTy)
inline MachineOpCode inline MachineOpCode
ChooseAddInstructionByType(const Type* resultType) ChooseAddInstructionByType(const Type* resultType)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = V9::INVALID_OPCODE;
if (resultType->isIntegral() || if (resultType->isIntegral() ||
isa<PointerType>(resultType) || isa<PointerType>(resultType) ||
isa<FunctionType>(resultType) || isa<FunctionType>(resultType) ||
resultType == Type::LabelTy) resultType == Type::LabelTy)
{ {
opCode = ADD; opCode = V9::ADD;
} }
else else
switch(resultType->getPrimitiveID()) switch(resultType->getPrimitiveID())
{ {
case Type::FloatTyID: opCode = FADDS; break; case Type::FloatTyID: opCode = V9::FADDS; break;
case Type::DoubleTyID: opCode = FADDD; break; case Type::DoubleTyID: opCode = V9::FADDD; break;
default: assert(0 && "Invalid type for ADD instruction"); break; default: assert(0 && "Invalid type for ADD instruction"); break;
} }
return opCode; return opCode;
} }

View File

@ -48,17 +48,19 @@ enum SparcInstrSchedClass {
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
enum SparcMachineOpCode { namespace V9 {
enum SparcMachineOpCode {
#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \ #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \ NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
ENUM, ENUM,
#include "SparcInstr.def" #include "SparcInstr.def"
// End-of-array marker // End-of-array marker
INVALID_OPCODE, INVALID_OPCODE,
NUM_REAL_OPCODES = PHI, // number of valid opcodes NUM_REAL_OPCODES = PHI, // number of valid opcodes
NUM_TOTAL_OPCODES = INVALID_OPCODE NUM_TOTAL_OPCODES = INVALID_OPCODE
}; };
}
// Array of machine instruction descriptions... // Array of machine instruction descriptions...
@ -84,21 +86,24 @@ struct UltraSparcInstrInfo : public TargetInstrInfo {
// //
virtual int getImmedConstantPos(MachineOpCode opCode) const { virtual int getImmedConstantPos(MachineOpCode opCode) const {
bool ignore; bool ignore;
if (this->maxImmedConstant(opCode, ignore) != 0) if (this->maxImmedConstant(opCode, ignore) != 0) {
{ // 1st store opcode
assert(! this->isStore((MachineOpCode) STB - 1)); // 1st store opcode assert(! this->isStore((MachineOpCode) V9::STB - 1));
assert(! this->isStore((MachineOpCode) STXFSR+1));// last store opcode // last store opcode
if (opCode==SETSW || opCode==SETUW || opCode==SETX || opCode==SETHI) assert(! this->isStore((MachineOpCode) V9::STXFSR + 1));
return 0;
if (opCode >= STB && opCode <= STXFSR) if (opCode == V9::SETSW || opCode == V9::SETUW ||
return 2; opCode == V9::SETX || opCode == V9::SETHI)
return 1; return 0;
} if (opCode >= V9::STB && opCode <= V9::STXFSR)
return 2;
return 1;
}
else else
return -1; return -1;
} }
virtual bool hasResultInterlock (MachineOpCode opCode) const virtual bool hasResultInterlock(MachineOpCode opCode) const
{ {
// All UltraSPARC instructions have interlocks (note that delay slots // All UltraSPARC instructions have interlocks (note that delay slots
// are not considered here). // are not considered here).
@ -106,7 +111,7 @@ struct UltraSparcInstrInfo : public TargetInstrInfo {
// 9-cycle stall if they are issued less than 3 cycles after the FCMP. // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
// Force the compiler to insert a software interlock (i.e., gap of // Force the compiler to insert a software interlock (i.e., gap of
// 2 other groups, including NOPs if necessary). // 2 other groups, including NOPs if necessary).
return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ); return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::FCMPQ);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -123,7 +128,7 @@ struct UltraSparcInstrInfo : public TargetInstrInfo {
// Get certain common op codes for the current target. This and all the // Get certain common op codes for the current target. This and all the
// Create* methods below should be moved to a machine code generation class // Create* methods below should be moved to a machine code generation class
// //
virtual MachineOpCode getNOPOpCode() const { return NOP; } virtual MachineOpCode getNOPOpCode() const { return V9::NOP; }
// Create an instruction sequence to put the constant `val' into // Create an instruction sequence to put the constant `val' into
// the virtual register `dest'. `val' may be a Constant or a // the virtual register `dest'. `val' may be a Constant or a
@ -699,7 +704,6 @@ struct UltraSparcOptInfo: public TargetOptInfo {
virtual bool IsUselessCopy (const MachineInstr* MI) const; virtual bool IsUselessCopy (const MachineInstr* MI) const;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// class UltraSparcMachine // class UltraSparcMachine
// //

View File

@ -61,9 +61,9 @@ void InsertPrologEpilogCode::InsertPrologCode(MachineFunction &MF)
int32_t C = - (int) staticStackSize; int32_t C = - (int) staticStackSize;
int SP = TM.getRegInfo().getStackPointer(); int SP = TM.getRegInfo().getStackPointer();
if (TM.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)) { if (TM.getInstrInfo().constantFitsInImmedField(V9::SAVE,staticStackSize)) {
mvec.push_back(BuildMI(SAVE, 3).addMReg(SP).addSImm(C).addMReg(SP, mvec.push_back(BuildMI(V9::SAVE, 3).addMReg(SP).addSImm(C).addMReg(SP,
MOTy::Def)); MOTy::Def));
} else { } else {
// We have to put the stack size value into a register before SAVE. // We have to put the stack size value into a register before SAVE.
// Use register %g1 since it is volatile across calls. Note that the // Use register %g1 since it is volatile across calls. Note that the
@ -74,19 +74,22 @@ void InsertPrologEpilogCode::InsertPrologCode(MachineFunction &MF)
TM.getRegInfo().getRegClassIDOfType(Type::IntTy), TM.getRegInfo().getRegClassIDOfType(Type::IntTy),
SparcIntRegClass::g1); SparcIntRegClass::g1);
MachineInstr* M = BuildMI(SETHI, 2).addSImm(C).addMReg(uregNum, MOTy::Def); MachineInstr* M = BuildMI(V9::SETHI, 2).addSImm(C)
.addMReg(uregNum, MOTy::Def);
M->setOperandHi32(0); M->setOperandHi32(0);
mvec.push_back(M); mvec.push_back(M);
M = BuildMI(OR, 3).addMReg(uregNum).addSImm(C).addMReg(uregNum, MOTy::Def); M = BuildMI(V9::OR, 3).addMReg(uregNum).addSImm(C)
.addMReg(uregNum, MOTy::Def);
M->setOperandLo32(1); M->setOperandLo32(1);
mvec.push_back(M); mvec.push_back(M);
M = BuildMI(SRA, 3).addMReg(uregNum).addZImm(0).addMReg(uregNum, MOTy::Def); M = BuildMI(V9::SRA, 3).addMReg(uregNum).addZImm(0)
.addMReg(uregNum, MOTy::Def);
mvec.push_back(M); mvec.push_back(M);
// Now generate the SAVE using the value in register %g1 // Now generate the SAVE using the value in register %g1
M = BuildMI(SAVE, 3).addMReg(SP).addMReg(uregNum).addMReg(SP, MOTy::Def); M = BuildMI(V9::SAVE, 3).addMReg(SP).addMReg(uregNum).addMReg(SP,MOTy::Def);
mvec.push_back(M); mvec.push_back(M);
} }
@ -103,34 +106,34 @@ void InsertPrologEpilogCode::InsertEpilogCode(MachineFunction &MF)
BasicBlock &BB = *I->getBasicBlock(); BasicBlock &BB = *I->getBasicBlock();
Instruction *TermInst = (Instruction*)BB.getTerminator(); Instruction *TermInst = (Instruction*)BB.getTerminator();
if (TermInst->getOpcode() == Instruction::Ret) if (TermInst->getOpcode() == Instruction::Ret)
{
int ZR = TM.getRegInfo().getZeroRegNum();
MachineInstr *Restore =
BuildMI(V9::RESTORE, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def);
MachineCodeForInstruction &termMvec =
MachineCodeForInstruction::get(TermInst);
// Remove the NOPs in the delay slots of the return instruction
unsigned numNOPs = 0;
while (termMvec.back()->getOpCode() == V9::NOP)
{ {
int ZR = TM.getRegInfo().getZeroRegNum(); assert( termMvec.back() == MBB.back());
MachineInstr *Restore = delete MBB.pop_back();
BuildMI(RESTORE, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def); termMvec.pop_back();
++numNOPs;
MachineCodeForInstruction &termMvec =
MachineCodeForInstruction::get(TermInst);
// Remove the NOPs in the delay slots of the return instruction
unsigned numNOPs = 0;
while (termMvec.back()->getOpCode() == NOP)
{
assert( termMvec.back() == MBB.back());
delete MBB.pop_back();
termMvec.pop_back();
++numNOPs;
}
assert(termMvec.back() == MBB.back());
// Check that we found the right number of NOPs and have the right
// number of instructions to replace them.
unsigned ndelays = MII.getNumDelaySlots(termMvec.back()->getOpCode());
assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
// Append the epilog code to the end of the basic block.
MBB.push_back(Restore);
} }
assert(termMvec.back() == MBB.back());
// Check that we found the right number of NOPs and have the right
// number of instructions to replace them.
unsigned ndelays = MII.getNumDelaySlots(termMvec.back()->getOpCode());
assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
assert(ndelays == 1 && "Cannot use epilog code for delay slots?");
// Append the epilog code to the end of the basic block.
MBB.push_back(Restore);
}
} }
} }

View File

@ -1106,18 +1106,17 @@ UltraSparcRegInfo::cpReg2RegMI(vector<MachineInstr*>& mvec,
switch( RegType ) { switch( RegType ) {
case IntCCRegType: case IntCCRegType:
if (getRegType(DestReg) == IntRegType) if (getRegType(DestReg) == IntRegType) {
{ // copy intCC reg to int reg // copy intCC reg to int reg
// Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
MI = BuildMI(RDCCR, 2).addMReg(SrcReg+1).addMReg(DestReg, MOTy::Def); MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(DestReg,MOTy::Def);
} } else {
else // copy int reg to intCC reg
{ // copy int reg to intCC reg // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
// Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR assert(getRegType(SrcReg) == IntRegType
assert(getRegType(SrcReg) == IntRegType && "Can only copy CC reg to/from integer reg");
&& "Can only copy CC reg to/from integer reg"); MI = BuildMI(V9::WRCCR, 2).addMReg(SrcReg).addMReg(DestReg+1, MOTy::Def);
MI = BuildMI(WRCCR, 2).addMReg(SrcReg).addMReg(DestReg+1, MOTy::Def); }
}
break; break;
case FloatCCRegType: case FloatCCRegType:
@ -1125,16 +1124,16 @@ UltraSparcRegInfo::cpReg2RegMI(vector<MachineInstr*>& mvec,
break; break;
case IntRegType: case IntRegType:
MI = BuildMI(ADD, 3).addMReg(SrcReg).addMReg(getZeroRegNum()) MI = BuildMI(V9::ADD, 3).addMReg(SrcReg).addMReg(getZeroRegNum())
.addMReg(DestReg, MOTy::Def); .addMReg(DestReg, MOTy::Def);
break; break;
case FPSingleRegType: case FPSingleRegType:
MI = BuildMI(FMOVS, 2).addMReg(SrcReg).addMReg(DestReg, MOTy::Def); MI = BuildMI(V9::FMOVS, 2).addMReg(SrcReg).addMReg(DestReg, MOTy::Def);
break; break;
case FPDoubleRegType: case FPDoubleRegType:
MI = BuildMI(FMOVD, 2).addMReg(SrcReg).addMReg(DestReg, MOTy::Def); MI = BuildMI(V9::FMOVD, 2).addMReg(SrcReg).addMReg(DestReg, MOTy::Def);
break; break;
default: default:
@ -1161,18 +1160,18 @@ UltraSparcRegInfo::cpReg2MemMI(vector<MachineInstr*>& mvec,
MachineInstr * MI = NULL; MachineInstr * MI = NULL;
switch (RegType) { switch (RegType) {
case IntRegType: case IntRegType:
assert(target.getInstrInfo().constantFitsInImmedField(STX, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::STX, Offset));
MI = BuildMI(STX, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset); MI = BuildMI(V9::STX,3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
break; break;
case FPSingleRegType: case FPSingleRegType:
assert(target.getInstrInfo().constantFitsInImmedField(ST, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::ST, Offset));
MI = BuildMI(ST, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset); MI = BuildMI(V9::ST, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
break; break;
case FPDoubleRegType: case FPDoubleRegType:
assert(target.getInstrInfo().constantFitsInImmedField(STD, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::STD, Offset));
MI = BuildMI(STD, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset); MI = BuildMI(V9::STD,3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
break; break;
case IntCCRegType: case IntCCRegType:
@ -1180,7 +1179,7 @@ UltraSparcRegInfo::cpReg2MemMI(vector<MachineInstr*>& mvec,
assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg"); assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
// Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
MI = BuildMI(RDCCR, 2).addMReg(SrcReg+1).addMReg(scratchReg, MOTy::Def); MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(scratchReg, MOTy::Def);
mvec.push_back(MI); mvec.push_back(MI);
cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType); cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType);
@ -1188,8 +1187,9 @@ UltraSparcRegInfo::cpReg2MemMI(vector<MachineInstr*>& mvec,
case FloatCCRegType: case FloatCCRegType:
assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here"); assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here");
assert(target.getInstrInfo().constantFitsInImmedField(STXFSR, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::STXFSR, Offset));
MI = BuildMI(STXFSR, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset); MI = BuildMI(V9::STXFSR, 3).addMReg(SrcReg).addMReg(DestPtrReg)
.addSImm(Offset);
break; break;
default: default:
@ -1215,20 +1215,20 @@ UltraSparcRegInfo::cpMem2RegMI(vector<MachineInstr*>& mvec,
MachineInstr * MI = NULL; MachineInstr * MI = NULL;
switch (RegType) { switch (RegType) {
case IntRegType: case IntRegType:
assert(target.getInstrInfo().constantFitsInImmedField(LDX, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::LDX, Offset));
MI = BuildMI(LDX, 3).addMReg(SrcPtrReg).addSImm(Offset) MI = BuildMI(V9::LDX, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(DestReg, MOTy::Def); .addMReg(DestReg, MOTy::Def);
break; break;
case FPSingleRegType: case FPSingleRegType:
assert(target.getInstrInfo().constantFitsInImmedField(LD, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::LD, Offset));
MI = BuildMI(LD, 3).addMReg(SrcPtrReg).addSImm(Offset) MI = BuildMI(V9::LD, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(DestReg, MOTy::Def); .addMReg(DestReg, MOTy::Def);
break; break;
case FPDoubleRegType: case FPDoubleRegType:
assert(target.getInstrInfo().constantFitsInImmedField(LDD, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::LDD, Offset));
MI = BuildMI(LDD, 3).addMReg(SrcPtrReg).addSImm(Offset).addMReg(DestReg, MI = BuildMI(V9::LDD, 3).addMReg(SrcPtrReg).addSImm(Offset).addMReg(DestReg,
MOTy::Def); MOTy::Def);
break; break;
@ -1238,15 +1238,15 @@ UltraSparcRegInfo::cpMem2RegMI(vector<MachineInstr*>& mvec,
cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType); cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType);
// Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
MI = BuildMI(WRCCR, 2).addMReg(scratchReg).addMReg(DestReg+1, MOTy::Def); MI = BuildMI(V9::WRCCR, 2).addMReg(scratchReg).addMReg(DestReg+1,MOTy::Def);
break; break;
case FloatCCRegType: case FloatCCRegType:
assert(0 && "Tell Vikram if this assertion fails: we may have to mask " assert(0 && "Tell Vikram if this assertion fails: we may have to mask "
"out the other bits here"); "out the other bits here");
assert(target.getInstrInfo().constantFitsInImmedField(LDXFSR, Offset)); assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXFSR, Offset));
MI = BuildMI(LDXFSR, 3).addMReg(SrcPtrReg).addSImm(Offset) MI = BuildMI(V9::LDXFSR, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(DestReg, MOTy::Def); .addMReg(DestReg, MOTy::Def);
break; break;
default: default:
@ -1270,13 +1270,14 @@ UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest,
switch( RegType ) { switch( RegType ) {
case IntRegType: case IntRegType:
MI = BuildMI(ADD, 3).addReg(Src).addMReg(getZeroRegNum()).addRegDef(Dest); MI = BuildMI(V9::ADD, 3).addReg(Src).addMReg(getZeroRegNum())
.addRegDef(Dest);
break; break;
case FPSingleRegType: case FPSingleRegType:
MI = BuildMI(FMOVS, 2).addReg(Src).addRegDef(Dest); MI = BuildMI(V9::FMOVS, 2).addReg(Src).addRegDef(Dest);
break; break;
case FPDoubleRegType: case FPDoubleRegType:
MI = BuildMI(FMOVD, 2).addReg(Src).addRegDef(Dest); MI = BuildMI(V9::FMOVD, 2).addReg(Src).addRegDef(Dest);
break; break;
default: default:
assert(0 && "Unknow RegType in CpValu2Value"); assert(0 && "Unknow RegType in CpValu2Value");

View File

@ -416,68 +416,68 @@ static const InstrIssueDelta SparcInstrIssueDeltas[] = {
// Special cases for single-issue only // Special cases for single-issue only
// Other single issue cases are below. // Other single issue cases are below.
//{ LDDA, true, true, 0 }, //{ V9::LDDA, true, true, 0 },
//{ STDA, true, true, 0 }, //{ V9::STDA, true, true, 0 },
//{ LDDF, true, true, 0 }, //{ V9::LDDF, true, true, 0 },
//{ LDDFA, true, true, 0 }, //{ V9::LDDFA, true, true, 0 },
{ ADDC, true, true, 0 }, { V9::ADDC, true, true, 0 },
{ ADDCcc, true, true, 0 }, { V9::ADDCcc, true, true, 0 },
{ SUBC, true, true, 0 }, { V9::SUBC, true, true, 0 },
{ SUBCcc, true, true, 0 }, { V9::SUBCcc, true, true, 0 },
//{ LDSTUB, true, true, 0 }, //{ V9::LDSTUB, true, true, 0 },
//{ SWAP, true, true, 0 }, //{ V9::SWAP, true, true, 0 },
//{ SWAPA, true, true, 0 }, //{ V9::SWAPA, true, true, 0 },
//{ CAS, true, true, 0 }, //{ V9::CAS, true, true, 0 },
//{ CASA, true, true, 0 }, //{ V9::CASA, true, true, 0 },
//{ CASX, true, true, 0 }, //{ V9::CASX, true, true, 0 },
//{ CASXA, true, true, 0 }, //{ V9::CASXA, true, true, 0 },
//{ LDFSR, true, true, 0 }, //{ V9::LDFSR, true, true, 0 },
//{ LDFSRA, true, true, 0 }, //{ V9::LDFSRA, true, true, 0 },
//{ LDXFSR, true, true, 0 }, //{ V9::LDXFSR, true, true, 0 },
//{ LDXFSRA, true, true, 0 }, //{ V9::LDXFSRA, true, true, 0 },
//{ STFSR, true, true, 0 }, //{ V9::STFSR, true, true, 0 },
//{ STFSRA, true, true, 0 }, //{ V9::STFSRA, true, true, 0 },
//{ STXFSR, true, true, 0 }, //{ V9::STXFSR, true, true, 0 },
//{ STXFSRA, true, true, 0 }, //{ V9::STXFSRA, true, true, 0 },
//{ SAVED, true, true, 0 }, //{ V9::SAVED, true, true, 0 },
//{ RESTORED, true, true, 0 }, //{ V9::RESTORED, true, true, 0 },
//{ FLUSH, true, true, 9 }, //{ V9::FLUSH, true, true, 9 },
//{ FLUSHW, true, true, 9 }, //{ V9::FLUSHW, true, true, 9 },
//{ ALIGNADDR, true, true, 0 }, //{ V9::ALIGNADDR, true, true, 0 },
{ RETURN, true, true, 0 }, { V9::RETURN, true, true, 0 },
//{ DONE, true, true, 0 }, //{ V9::DONE, true, true, 0 },
//{ RETRY, true, true, 0 }, //{ V9::RETRY, true, true, 0 },
//{ TCC, true, true, 0 }, //{ V9::TCC, true, true, 0 },
//{ SHUTDOWN, true, true, 0 }, //{ V9::SHUTDOWN, true, true, 0 },
// Special cases for breaking group *before* // Special cases for breaking group *before*
// CURRENTLY NOT SUPPORTED! // CURRENTLY NOT SUPPORTED!
{ CALL, false, false, 0 }, { V9::CALL, false, false, 0 },
{ JMPLCALL, false, false, 0 }, { V9::JMPLCALL, false, false, 0 },
{ JMPLRET, false, false, 0 }, { V9::JMPLRET, false, false, 0 },
// Special cases for breaking the group *after* // Special cases for breaking the group *after*
{ MULX, true, true, (4+34)/2 }, { V9::MULX, true, true, (4+34)/2 },
{ FDIVS, false, true, 0 }, { V9::FDIVS, false, true, 0 },
{ FDIVD, false, true, 0 }, { V9::FDIVD, false, true, 0 },
{ FDIVQ, false, true, 0 }, { V9::FDIVQ, false, true, 0 },
{ FSQRTS, false, true, 0 }, { V9::FSQRTS, false, true, 0 },
{ FSQRTD, false, true, 0 }, { V9::FSQRTD, false, true, 0 },
{ FSQRTQ, false, true, 0 }, { V9::FSQRTQ, false, true, 0 },
//{ FCMP{LE,GT,NE,EQ}, false, true, 0 }, //{ V9::FCMP{LE,GT,NE,EQ}, false, true, 0 },
// Instructions that introduce bubbles // Instructions that introduce bubbles
//{ MULScc, true, true, 2 }, //{ V9::MULScc, true, true, 2 },
//{ SMULcc, true, true, (4+18)/2 }, //{ V9::SMULcc, true, true, (4+18)/2 },
//{ UMULcc, true, true, (4+19)/2 }, //{ V9::UMULcc, true, true, (4+19)/2 },
{ SDIVX, true, true, 68 }, { V9::SDIVX, true, true, 68 },
{ UDIVX, true, true, 68 }, { V9::UDIVX, true, true, 68 },
//{ SDIVcc, true, true, 36 }, //{ V9::SDIVcc, true, true, 36 },
//{ UDIVcc, true, true, 37 }, //{ V9::UDIVcc, true, true, 37 },
{ WRCCR, true, true, 4 }, { V9::WRCCR, true, true, 4 },
//{ WRPR, true, true, 4 }, //{ V9::WRPR, true, true, 4 },
//{ RDCCR, true, true, 0 }, // no bubbles after, but see below //{ V9::RDCCR, true, true, 0 }, // no bubbles after, but see below
//{ RDPR, true, true, 0 }, //{ V9::RDPR, true, true, 0 },
}; };
@ -498,59 +498,59 @@ static const InstrRUsageDelta SparcInstrUsageDeltas[] = {
// //
// JMPL counts as a load/store instruction for issue! // JMPL counts as a load/store instruction for issue!
// //
{ JMPLCALL, LSIssueSlots.rid, 0, 1 }, { V9::JMPLCALL, LSIssueSlots.rid, 0, 1 },
{ JMPLRET, LSIssueSlots.rid, 0, 1 }, { V9::JMPLRET, LSIssueSlots.rid, 0, 1 },
// //
// Many instructions cannot issue for the next 2 cycles after an FCMP // Many instructions cannot issue for the next 2 cycles after an FCMP
// We model that with a fake resource FCMPDelayCycle. // We model that with a fake resource FCMPDelayCycle.
// //
{ FCMPS, FCMPDelayCycle.rid, 1, 3 }, { V9::FCMPS, FCMPDelayCycle.rid, 1, 3 },
{ FCMPD, FCMPDelayCycle.rid, 1, 3 }, { V9::FCMPD, FCMPDelayCycle.rid, 1, 3 },
{ FCMPQ, FCMPDelayCycle.rid, 1, 3 }, { V9::FCMPQ, FCMPDelayCycle.rid, 1, 3 },
{ MULX, FCMPDelayCycle.rid, 1, 1 }, { V9::MULX, FCMPDelayCycle.rid, 1, 1 },
{ SDIVX, FCMPDelayCycle.rid, 1, 1 }, { V9::SDIVX, FCMPDelayCycle.rid, 1, 1 },
{ UDIVX, FCMPDelayCycle.rid, 1, 1 }, { V9::UDIVX, FCMPDelayCycle.rid, 1, 1 },
//{ SMULcc, FCMPDelayCycle.rid, 1, 1 }, //{ V9::SMULcc, FCMPDelayCycle.rid, 1, 1 },
//{ UMULcc, FCMPDelayCycle.rid, 1, 1 }, //{ V9::UMULcc, FCMPDelayCycle.rid, 1, 1 },
//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 }, //{ V9::SDIVcc, FCMPDelayCycle.rid, 1, 1 },
//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 }, //{ V9::UDIVcc, FCMPDelayCycle.rid, 1, 1 },
{ STD, FCMPDelayCycle.rid, 1, 1 }, { V9::STD, FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSZ, FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
{ FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 }, { V9::FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
// //
// Some instructions are stalled in the GROUP stage if a CTI is in // Some instructions are stalled in the GROUP stage if a CTI is in
// the E or C stage. We model that with a fake resource CTIDelayCycle. // the E or C stage. We model that with a fake resource CTIDelayCycle.
// //
{ LDD, CTIDelayCycle.rid, 1, 1 }, { V9::LDD, CTIDelayCycle.rid, 1, 1 },
//{ LDDA, CTIDelayCycle.rid, 1, 1 }, //{ V9::LDDA, CTIDelayCycle.rid, 1, 1 },
//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 }, //{ V9::LDDSTUB, CTIDelayCycle.rid, 1, 1 },
//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 }, //{ V9::LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
//{ SWAP, CTIDelayCycle.rid, 1, 1 }, //{ V9::SWAP, CTIDelayCycle.rid, 1, 1 },
//{ SWAPA, CTIDelayCycle.rid, 1, 1 }, //{ V9::SWAPA, CTIDelayCycle.rid, 1, 1 },
//{ CAS, CTIDelayCycle.rid, 1, 1 }, //{ V9::CAS, CTIDelayCycle.rid, 1, 1 },
//{ CASA, CTIDelayCycle.rid, 1, 1 }, //{ V9::CASA, CTIDelayCycle.rid, 1, 1 },
//{ CASX, CTIDelayCycle.rid, 1, 1 }, //{ V9::CASX, CTIDelayCycle.rid, 1, 1 },
//{ CASXA, CTIDelayCycle.rid, 1, 1 }, //{ V9::CASXA, CTIDelayCycle.rid, 1, 1 },
// //
// Signed int loads of less than dword size return data in cycle N1 (not C) // Signed int loads of less than dword size return data in cycle N1 (not C)
// and put all loads in consecutive cycles into delayed load return mode. // and put all loads in consecutive cycles into delayed load return mode.
// //
{ LDSB, LdReturn.rid, 2, -1 }, { V9::LDSB, LdReturn.rid, 2, -1 },
{ LDSB, LdReturn.rid, 3, 1 }, { V9::LDSB, LdReturn.rid, 3, 1 },
{ LDSH, LdReturn.rid, 2, -1 }, { V9::LDSH, LdReturn.rid, 2, -1 },
{ LDSH, LdReturn.rid, 3, 1 }, { V9::LDSH, LdReturn.rid, 3, 1 },
{ LDSW, LdReturn.rid, 2, -1 }, { V9::LDSW, LdReturn.rid, 2, -1 },
{ LDSW, LdReturn.rid, 3, 1 }, { V9::LDSW, LdReturn.rid, 3, 1 },
// //
// RDPR from certain registers and RD from any register are not dispatchable // RDPR from certain registers and RD from any register are not dispatchable
@ -559,10 +559,10 @@ static const InstrRUsageDelta SparcInstrUsageDeltas[] = {
// slots are effectively blocked for those cycles, plus the issue cycle. // slots are effectively blocked for those cycles, plus the issue cycle.
// This does not increase the latency of the instruction itself. // This does not increase the latency of the instruction itself.
// //
{ RDCCR, AllIssueSlots.rid, 0, 5 }, { V9::RDCCR, AllIssueSlots.rid, 0, 5 },
{ RDCCR, AllIssueSlots.rid, 0, 5 }, { V9::RDCCR, AllIssueSlots.rid, 0, 5 },
{ RDCCR, AllIssueSlots.rid, 0, 5 }, { V9::RDCCR, AllIssueSlots.rid, 0, 5 },
{ RDCCR, AllIssueSlots.rid, 0, 5 }, { V9::RDCCR, AllIssueSlots.rid, 0, 5 },
#undef EXPLICIT_BUBBLES_NEEDED #undef EXPLICIT_BUBBLES_NEEDED
#ifdef EXPLICIT_BUBBLES_NEEDED #ifdef EXPLICIT_BUBBLES_NEEDED
@ -571,95 +571,95 @@ static const InstrRUsageDelta SparcInstrUsageDeltas[] = {
// This means it breaks the current group (captured in UltraSparcSchedInfo) // This means it breaks the current group (captured in UltraSparcSchedInfo)
// *and occupies all issue slots for the next cycle // *and occupies all issue slots for the next cycle
// //
//{ MULScc, AllIssueSlots.rid, 2, 2-1 }, //{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//{ MULScc, AllIssueSlots.rid, 2, 2-1 }, //{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//{ MULScc, AllIssueSlots.rid, 2, 2-1 }, //{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//{ MULScc, AllIssueSlots.rid, 2, 2-1 }, //{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
// //
// SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1. // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
// We just model this with a simple average. // We just model this with a simple average.
// //
//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 }, //{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 }, //{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 }, //{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 }, //{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
// SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1. // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 }, //{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 }, //{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 }, //{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 }, //{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
// //
// MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1. // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
// //
{ MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 }, { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
{ MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 }, { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
{ MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 }, { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
{ MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 }, { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
// //
// SDIVcc inserts 36 bubbles. // SDIVcc inserts 36 bubbles.
// //
//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 }, //{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 }, //{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 }, //{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 }, //{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
// UDIVcc inserts 37 bubbles. // UDIVcc inserts 37 bubbles.
//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 }, //{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 }, //{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 }, //{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 }, //{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
// //
// SDIVX inserts 68 bubbles. // SDIVX inserts 68 bubbles.
// //
{ SDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
{ SDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
{ SDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
{ SDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
// //
// UDIVX inserts 68 bubbles. // UDIVX inserts 68 bubbles.
// //
{ UDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
{ UDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
{ UDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
{ UDIVX, AllIssueSlots.rid, 2, 68-1 }, { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
// //
// WR inserts 4 bubbles. // WR inserts 4 bubbles.
// //
//{ WR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//{ WR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//{ WR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//{ WR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
// //
// WRPR inserts 4 bubbles. // WRPR inserts 4 bubbles.
// //
//{ WRPR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//{ WRPR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//{ WRPR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//{ WRPR, AllIssueSlots.rid, 2, 68-1 }, //{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
// //
// DONE inserts 9 bubbles. // DONE inserts 9 bubbles.
// //
//{ DONE, AllIssueSlots.rid, 2, 9-1 }, //{ V9::DONE, AllIssueSlots.rid, 2, 9-1 },
//{ DONE, AllIssueSlots.rid, 2, 9-1 }, //{ V9::DONE, AllIssueSlots.rid, 2, 9-1 },
//{ DONE, AllIssueSlots.rid, 2, 9-1 }, //{ V9::DONE, AllIssueSlots.rid, 2, 9-1 },
//{ DONE, AllIssueSlots.rid, 2, 9-1 }, //{ V9::DONE, AllIssueSlots.rid, 2, 9-1 },
// //
// RETRY inserts 9 bubbles. // RETRY inserts 9 bubbles.
// //
//{ RETRY, AllIssueSlots.rid, 2, 9-1 }, //{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
//{ RETRY, AllIssueSlots.rid, 2, 9-1 }, //{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
//{ RETRY, AllIssueSlots.rid, 2, 9-1 }, //{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
//{ RETRY, AllIssueSlots.rid, 2, 9-1 }, //{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
#endif /*EXPLICIT_BUBBLES_NEEDED */ #endif /*EXPLICIT_BUBBLES_NEEDED */
}; };