SparcCodeEmitter.cpp revision 38aceb871478893bfa87f94c2cb3a344a4c8c2df
166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis//===-- Sparc/SparcCodeEmitter.cpp - Convert Sparc Code to Machine Code ---===// 266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// 366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// The LLVM Compiler Infrastructure 466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// 566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// This file is distributed under the University of Illinois Open Source 666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// License. See LICENSE.TXT for details. 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// 866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis//===---------------------------------------------------------------------===// 966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// 1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// This file contains the pass that transforms the Sparc machine instructions 1166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// into relocatable machine code. 1266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// 1366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis//===---------------------------------------------------------------------===// 1466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#define DEBUG_TYPE "jit" 1666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "Sparc.h" 1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "MCTargetDesc/SparcBaseInfo.h" 1866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "SparcRelocations.h" 1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "SparcTargetMachine.h" 2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "llvm/ADT/Statistic.h" 2166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "llvm/CodeGen/JITCodeEmitter.h" 2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "llvm/CodeGen/MachineFunctionPass.h" 2366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "llvm/CodeGen/MachineModuleInfo.h" 2466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis#include "llvm/Support/Debug.h" 2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisusing namespace llvm; 2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2866a37686207944273ced825e0e8b6b6375f8c3deJamie GennisSTATISTIC(NumEmitted, "Number of machine instructions emitted"); 2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisnamespace { 3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisclass SparcCodeEmitter : public MachineFunctionPass { 3366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis SparcJITInfo *JTI; 3466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const SparcInstrInfo *II; 3566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const DataLayout *TD; 3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const SparcSubtarget *Subtarget; 3766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis TargetMachine &TM; 3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis JITCodeEmitter &MCE; 3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const std::vector<MachineConstantPoolEntry> *MCPEs; 4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bool IsPIC; 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void getAnalysisUsage(AnalysisUsage &AU) const { 4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis AU.addRequired<MachineModuleInfo> (); 4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MachineFunctionPass::getAnalysisUsage(AU); 4566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis static char ID; 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennispublic: 5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) 5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis : MachineFunctionPass(ID), JTI(0), II(0), TD(0), 5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis TM(tm), MCE(mce), MCPEs(0), 5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bool runOnMachineFunction(MachineFunction &MF); 5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis virtual const char *getPassName() const { 5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return "Sparc Machine Code Emitter"; 5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /// getBinaryCodeForInstr - This function, generated by the 6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /// CodeEmitterGenerator using TableGen, produces the binary encoding for 6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /// machine instructions. 6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitInstruction(MachineBasicBlock::instr_iterator MI, 6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MachineBasicBlock &MBB); 6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisprivate: 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /// getMachineOpValue - Return binary encoding of operand. If the machine 7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /// operand requires relocation, record the relocation and return zero. 7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis unsigned getMachineOpValue(const MachineInstr &MI, 7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const MachineOperand &MO) const; 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitWord(unsigned Word); 7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis unsigned getRelocation(const MachineInstr &MI, 7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const MachineOperand &MO) const; 7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc) const; 8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis}; 8566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis} // end anonymous namespace. 8666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennischar SparcCodeEmitter::ID = 0; 8866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbool SparcCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 9066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis SparcTargetMachine &Target = static_cast<SparcTargetMachine &>( 9166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const_cast<TargetMachine &>(MF.getTarget())); 9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis JTI = Target.getJITInfo(); 9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis II = Target.getInstrInfo(); 9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis TD = Target.getDataLayout(); 9666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Subtarget = &TM.getSubtarget<SparcSubtarget> (); 9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCPEs = &MF.getConstantPool()->getConstants(); 9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis JTI->Initialize(MF, IsPIC); 9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis do { 10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis DEBUG(errs() << "JITTing function '" 10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis << MF.getName() << "'\n"); 10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.startFunction(MF); 10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MBB != E; ++MBB){ 10866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.StartMachineBasicBlock(MBB); 10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(), 11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis E = MBB->instr_end(); I != E;) 11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitInstruction(*I++, *MBB); 11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } while (MCE.finishFunction(MF)); 11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return false; 11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis} 11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisvoid SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, 11966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MachineBasicBlock &MBB) { 12066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); 12166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 12266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.processDebugLoc(MI->getDebugLoc(), true); 12366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 12466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ++NumEmitted; 12566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 12666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis switch (MI->getOpcode()) { 12766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis default: { 12866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitWord(getBinaryCodeForInstr(*MI)); 12966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 13066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 13166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case TargetOpcode::INLINEASM: { 13266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // We allow inline assembler nodes with empty bodies - they can 13366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // implicitly define registers, which is ok for JIT. 13466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (MI->getOperand(0).getSymbolName()[0]) { 13566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis report_fatal_error("JIT does not support inline asm!"); 13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 13766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 13866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 13966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case TargetOpcode::PROLOG_LABEL: 14066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case TargetOpcode::EH_LABEL: { 14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.emitLabel(MI->getOperand(0).getMCSymbol()); 14266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 14366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 14466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case TargetOpcode::IMPLICIT_DEF: 14566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case TargetOpcode::KILL: { 14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // Do nothing. 14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SP::GETPCX: { 15066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis report_fatal_error("JIT does not support pseudo instruction GETPCX yet!"); 15166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 15266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 15366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 15466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 15566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.processDebugLoc(MI->getDebugLoc(), false); 15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis} 15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisvoid SparcCodeEmitter::emitWord(unsigned Word) { 15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis DEBUG(errs() << " 0x"; 16066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis errs().write_hex(Word) << "\n"); 16166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis MCE.emitWordBE(Word); 16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis} 16366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 16466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/// getMachineOpValue - Return binary encoding of operand. If the machine 16566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/// operand requires relocation, record the relocation and return zero. 16666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisunsigned SparcCodeEmitter::getMachineOpValue(const MachineInstr &MI, 16766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const MachineOperand &MO) const { 16866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (MO.isReg()) 16966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 17066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else if (MO.isImm()) 17166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return static_cast<unsigned>(MO.getImm()); 17266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else if (MO.isGlobal()) 17366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO)); 17466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else if (MO.isSymbol()) 17566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 17666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else if (MO.isCPI()) 17766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 17866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else if (MO.isMBB()) 17966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 18066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else 18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis llvm_unreachable("Unable to encode MachineOperand!"); 18266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return 0; 18366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis} 18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisunsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, 18566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis const MachineOperand &MO) const { 18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 18766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis unsigned TF = MO.getTargetFlags(); 18866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis switch (TF) { 18966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis default: 19066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_NO_FLAG: break; 19166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_LO: return SP::reloc_sparc_lo; 19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_HI: return SP::reloc_sparc_hi; 19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_H44: 19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_M44: 19566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_L44: 19666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_HH: 19766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis case SPII::MO_HM: assert(0 && "FIXME: Implement Medium/Large code model."); 19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 20066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis unsigned Opc = MI.getOpcode(); 20166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis switch (Opc) { 202 default: break; 203 case SP::CALL: return SP::reloc_sparc_pc30; 204 case SP::BA: 205 case SP::BCOND: 206 case SP::FBCOND: return SP::reloc_sparc_pc22; 207 case SP::BPXCC: return SP::reloc_sparc_pc19; 208 } 209 llvm_unreachable("unknown reloc!"); 210} 211 212void SparcCodeEmitter::emitGlobalAddress(const GlobalValue *GV, 213 unsigned Reloc) const { 214 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 215 const_cast<GlobalValue *>(GV), 0, 216 true)); 217} 218 219void SparcCodeEmitter:: 220emitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 221 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 222 Reloc, ES, 0, 0)); 223} 224 225void SparcCodeEmitter:: 226emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 227 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 228 Reloc, CPI, 0, false)); 229} 230 231void SparcCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 232 unsigned Reloc) const { 233 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 234 Reloc, BB)); 235} 236 237 238/// createSparcJITCodeEmitterPass - Return a pass that emits the collected Sparc 239/// code to the specified MCE object. 240FunctionPass *llvm::createSparcJITCodeEmitterPass(SparcTargetMachine &TM, 241 JITCodeEmitter &JCE) { 242 return new SparcCodeEmitter(TM, JCE); 243} 244 245#include "SparcGenCodeEmitter.inc" 246