//===-- llvm/CodeGen/SparcInstrSelectionSupport.h ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // TODO: Need a description here. // //===----------------------------------------------------------------------===// #ifndef SPARC_INSTR_SELECTION_SUPPORT_h #define SPARC_INSTR_SELECTION_SUPPORT_h #include "llvm/DerivedTypes.h" #include "SparcInternals.h" // Choose load instruction opcode based on type of value inline MachineOpCode ChooseLoadInstruction(const Type *DestTy) { switch (DestTy->getPrimitiveID()) { case Type::BoolTyID: case Type::UByteTyID: return V9::LDUBr; case Type::SByteTyID: return V9::LDSBr; case Type::UShortTyID: return V9::LDUHr; case Type::ShortTyID: return V9::LDSHr; case Type::UIntTyID: return V9::LDUWr; case Type::IntTyID: return V9::LDSWr; case Type::PointerTyID: case Type::ULongTyID: case Type::LongTyID: return V9::LDXr; case Type::FloatTyID: return V9::LDFr; case Type::DoubleTyID: return V9::LDDFr; default: assert(0 && "Invalid type for Load instruction"); } return 0; } // Choose store instruction opcode based on type of value inline MachineOpCode ChooseStoreInstruction(const Type *DestTy) { switch (DestTy->getPrimitiveID()) { case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID: return V9::STBr; case Type::UShortTyID: case Type::ShortTyID: return V9::STHr; case Type::UIntTyID: case Type::IntTyID: return V9::STWr; case Type::PointerTyID: case Type::ULongTyID: case Type::LongTyID: return V9::STXr; case Type::FloatTyID: return V9::STFr; case Type::DoubleTyID: return V9::STDFr; default: assert(0 && "Invalid type for Store instruction"); } return 0; } inline MachineOpCode ChooseAddInstructionByType(const Type* resultType) { MachineOpCode opCode = V9::INVALID_OPCODE; if (resultType->isIntegral() || isa(resultType) || isa(resultType) || resultType == Type::LabelTy) { opCode = V9::ADDr; } else switch(resultType->getPrimitiveID()) { case Type::FloatTyID: opCode = V9::FADDS; break; case Type::DoubleTyID: opCode = V9::FADDD; break; default: assert(0 && "Invalid type for ADD instruction"); break; } return opCode; } // Because the Sparc instruction selector likes to re-write operands to // instructions, making them change from a Value* (virtual register) to a // Constant* (making an immediate field), we need to change the opcode from a // register-based instruction to an immediate-based instruction, hence this // mapping. static unsigned convertOpcodeFromRegToImm(unsigned Opcode) { switch (Opcode) { /* arithmetic */ case V9::ADDr: return V9::ADDi; case V9::ADDccr: return V9::ADDcci; case V9::ADDCr: return V9::ADDCi; case V9::ADDCccr: return V9::ADDCcci; case V9::SUBr: return V9::SUBi; case V9::SUBccr: return V9::SUBcci; case V9::SUBCr: return V9::SUBCi; case V9::SUBCccr: return V9::SUBCcci; case V9::MULXr: return V9::MULXi; case V9::SDIVXr: return V9::SDIVXi; case V9::UDIVXr: return V9::UDIVXi; /* logical */ case V9::ANDr: return V9::ANDi; case V9::ANDccr: return V9::ANDcci; case V9::ANDNr: return V9::ANDNi; case V9::ANDNccr: return V9::ANDNcci; case V9::ORr: return V9::ORi; case V9::ORccr: return V9::ORcci; case V9::ORNr: return V9::ORNi; case V9::ORNccr: return V9::ORNcci; case V9::XORr: return V9::XORi; case V9::XORccr: return V9::XORcci; case V9::XNORr: return V9::XNORi; case V9::XNORccr: return V9::XNORcci; /* shift */ case V9::SLLr5: return V9::SLLi5; case V9::SRLr5: return V9::SRLi5; case V9::SRAr5: return V9::SRAi5; case V9::SLLXr6: return V9::SLLXi6; case V9::SRLXr6: return V9::SRLXi6; case V9::SRAXr6: return V9::SRAXi6; /* Conditional move on int comparison with zero */ case V9::MOVRZr: return V9::MOVRZi; case V9::MOVRLEZr: return V9::MOVRLEZi; case V9::MOVRLZr: return V9::MOVRLZi; case V9::MOVRNZr: return V9::MOVRNZi; case V9::MOVRGZr: return V9::MOVRGZi; case V9::MOVRGEZr: return V9::MOVRGEZi; /* Conditional move on int condition code */ case V9::MOVAr: return V9::MOVAi; case V9::MOVNr: return V9::MOVNi; case V9::MOVNEr: return V9::MOVNEi; case V9::MOVEr: return V9::MOVEi; case V9::MOVGr: return V9::MOVGi; case V9::MOVLEr: return V9::MOVLEi; case V9::MOVGEr: return V9::MOVGEi; case V9::MOVLr: return V9::MOVLi; case V9::MOVGUr: return V9::MOVGUi; case V9::MOVLEUr: return V9::MOVLEUi; case V9::MOVCCr: return V9::MOVCCi; case V9::MOVCSr: return V9::MOVCSi; case V9::MOVPOSr: return V9::MOVPOSi; case V9::MOVNEGr: return V9::MOVNEGi; case V9::MOVVCr: return V9::MOVVCi; case V9::MOVVSr: return V9::MOVVSi; /* Conditional move of int reg on fp condition code */ case V9::MOVFAr: return V9::MOVFAi; case V9::MOVFNr: return V9::MOVFNi; case V9::MOVFUr: return V9::MOVFUi; case V9::MOVFGr: return V9::MOVFGi; case V9::MOVFUGr: return V9::MOVFUGi; case V9::MOVFLr: return V9::MOVFLi; case V9::MOVFULr: return V9::MOVFULi; case V9::MOVFLGr: return V9::MOVFLGi; case V9::MOVFNEr: return V9::MOVFNEi; case V9::MOVFEr: return V9::MOVFEi; case V9::MOVFUEr: return V9::MOVFUEi; case V9::MOVFGEr: return V9::MOVFGEi; case V9::MOVFUGEr: return V9::MOVFUGEi; case V9::MOVFLEr: return V9::MOVFLEi; case V9::MOVFULEr: return V9::MOVFULEi; case V9::MOVFOr: return V9::MOVFOi; /* load */ case V9::LDSBr: return V9::LDSBi; case V9::LDSHr: return V9::LDSHi; case V9::LDSWr: return V9::LDSWi; case V9::LDUBr: return V9::LDUBi; case V9::LDUHr: return V9::LDUHi; case V9::LDUWr: return V9::LDUWi; case V9::LDXr: return V9::LDXi; case V9::LDFr: return V9::LDFi; case V9::LDDFr: return V9::LDDFi; case V9::LDQFr: return V9::LDQFi; case V9::LDFSRr: return V9::LDFSRi; case V9::LDXFSRr: return V9::LDXFSRi; /* store */ case V9::STBr: return V9::STBi; case V9::STHr: return V9::STHi; case V9::STWr: return V9::STWi; case V9::STXr: return V9::STXi; case V9::STFr: return V9::STFi; case V9::STDFr: return V9::STDFi; case V9::STFSRr: return V9::STFSRi; case V9::STXFSRr: return V9::STXFSRi; /* jump & return */ case V9::JMPLCALLr: return V9::JMPLCALLi; case V9::JMPLRETr: return V9::JMPLRETi; case V9::RETURNr: return V9::RETURNi; /* save and restore */ case V9::SAVEr: return V9::SAVEi; case V9::RESTOREr: return V9::RESTOREi; default: // It's already in correct format // Or, it's just not handled yet, but an assert() would break LLC #if 0 std::cerr << "Unhandled opcode in convertOpcodeFromRegToImm(): " << Opcode << "\n"; #endif return Opcode; } } #endif