X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FInstSelectSimple.cpp;h=e1515672648d670c5cd61af5eaa7c9eb8c2cb3e9;hb=b576c94c15af9a440f69d9d03c2afead7971118c;hp=1df8cb8ca1181e152e57bbac5a357e96953eaea0;hpb=c01d1232fe5a25d807c7ab975437ef6c514d2cd6;p=oota-llvm.git diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 1df8cb8ca11..e1515672648 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -1,4 +1,11 @@ //===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines a simple peephole instruction selector for the x86 target // @@ -162,11 +169,7 @@ namespace { MachineBasicBlock::iterator &MBBI); // Memory Instructions - MachineInstr *doFPLoad(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - const Type *Ty, unsigned DestReg); void visitLoadInst(LoadInst &I); - void doFPStore(const Type *Ty, unsigned DestAddrReg, unsigned SrcReg); void visitStoreInst(StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); void visitAllocaInst(AllocaInst &I); @@ -401,7 +404,11 @@ void ISel::copyConstantToRegister(MachineBasicBlock *MBB, // Otherwise we need to spill the constant to memory... MachineConstantPool *CP = F->getConstantPool(); unsigned CPI = CP->getConstantPoolIndex(CFP); - addConstantPoolReference(doFPLoad(MBB, IP, CFP->getType(), R), CPI); + const Type *Ty = CFP->getType(); + + assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!"); + unsigned LoadOpcode = Ty == Type::FloatTy ? X86::FLDr32 : X86::FLDr64; + addConstantPoolReference(BMI(MBB, IP, LoadOpcode, 4, R), CPI); } } else if (isa(C)) { @@ -1536,52 +1543,6 @@ void ISel::visitShiftInst(ShiftInst &I) { } -/// doFPLoad - This method is used to load an FP value from memory using the -/// current endianness. NOTE: This method returns a partially constructed load -/// instruction which needs to have the memory source filled in still. -/// -MachineInstr *ISel::doFPLoad(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - const Type *Ty, unsigned DestReg) { - assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!"); - unsigned LoadOpcode = Ty == Type::FloatTy ? X86::FLDr32 : X86::FLDr64; - - if (TM.getTargetData().isLittleEndian()) // fast path... - return BMI(MBB, MBBI, LoadOpcode, 4, DestReg); - - // If we are big-endian, start by creating an LEA instruction to represent the - // address of the memory location to load from... - // - unsigned SrcAddrReg = makeAnotherReg(Type::UIntTy); - MachineInstr *Result = BMI(MBB, MBBI, X86::LEAr32, 5, SrcAddrReg); - - // Allocate a temporary stack slot to transform the value into... - int FrameIdx = F->getFrameInfo()->CreateStackObject(Ty, TM.getTargetData()); - - // Perform the bswaps 32 bits at a time... - unsigned TmpReg1 = makeAnotherReg(Type::UIntTy); - unsigned TmpReg2 = makeAnotherReg(Type::UIntTy); - addDirectMem(BMI(MBB, MBBI, X86::MOVmr32, 4, TmpReg1), SrcAddrReg); - BMI(MBB, MBBI, X86::BSWAPr32, 1, TmpReg2).addReg(TmpReg1); - unsigned Offset = (Ty == Type::DoubleTy) << 2; - addFrameReference(BMI(MBB, MBBI, X86::MOVrm32, 5), - FrameIdx, Offset).addReg(TmpReg2); - - if (Ty == Type::DoubleTy) { // Swap the other 32 bits of a double value... - TmpReg1 = makeAnotherReg(Type::UIntTy); - TmpReg2 = makeAnotherReg(Type::UIntTy); - - addRegOffset(BMI(MBB, MBBI, X86::MOVmr32, 4, TmpReg1), SrcAddrReg, 4); - BMI(MBB, MBBI, X86::BSWAPr32, 1, TmpReg2).addReg(TmpReg1); - unsigned Offset = (Ty == Type::DoubleTy) << 2; - addFrameReference(BMI(MBB, MBBI, X86::MOVrm32,5), FrameIdx).addReg(TmpReg2); - } - - // Now we can reload the final byteswapped result into the final destination. - addFrameReference(BMI(MBB, MBBI, LoadOpcode, 4, DestReg), FrameIdx); - return Result; -} - /// EmitByteSwap - Byteswap SrcReg into DestReg. /// void ISel::EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class) { @@ -1616,150 +1577,47 @@ void ISel::EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class) { /// need to worry about the memory layout of the target machine. /// void ISel::visitLoadInst(LoadInst &I) { - bool isLittleEndian = TM.getTargetData().isLittleEndian(); - bool hasLongPointers = TM.getTargetData().getPointerSize() == 8; unsigned SrcAddrReg = getReg(I.getOperand(0)); unsigned DestReg = getReg(I); unsigned Class = getClassB(I.getType()); - switch (Class) { - case cFP: { - MachineBasicBlock::iterator MBBI = BB->end(); - addDirectMem(doFPLoad(BB, MBBI, I.getType(), DestReg), SrcAddrReg); - return; - } - case cLong: case cInt: case cShort: case cByte: - break; // Integers of various sizes handled below - default: assert(0 && "Unknown memory class!"); - } - - // We need to adjust the input pointer if we are emulating a big-endian - // long-pointer target. On these systems, the pointer that we are interested - // in is in the upper part of the eight byte memory image of the pointer. It - // also happens to be byte-swapped, but this will be handled later. - // - if (!isLittleEndian && hasLongPointers && isa(I.getType())) { - unsigned R = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDri32, 2, R).addReg(SrcAddrReg).addZImm(4); - SrcAddrReg = R; - } - - unsigned IReg = DestReg; - if (!isLittleEndian) // If big endian we need an intermediate stage - DestReg = makeAnotherReg(Class != cLong ? I.getType() : Type::UIntTy); - - static const unsigned Opcode[] = { - X86::MOVmr8, X86::MOVmr16, X86::MOVmr32, 0, X86::MOVmr32 - }; - addDirectMem(BuildMI(BB, Opcode[Class], 4, DestReg), SrcAddrReg); - // Handle long values now... if (Class == cLong) { - if (isLittleEndian) { - addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), SrcAddrReg, 4); - } else { - EmitByteSwap(IReg+1, DestReg, cInt); - unsigned TempReg = makeAnotherReg(Type::IntTy); - addRegOffset(BuildMI(BB, X86::MOVmr32, 4, TempReg), SrcAddrReg, 4); - EmitByteSwap(IReg, TempReg, cInt); - } + addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), SrcAddrReg); + addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), SrcAddrReg, 4); return; } - if (!isLittleEndian) - EmitByteSwap(IReg, DestReg, Class); -} - - -/// doFPStore - This method is used to store an FP value to memory using the -/// current endianness. -/// -void ISel::doFPStore(const Type *Ty, unsigned DestAddrReg, unsigned SrcReg) { - assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!"); - unsigned StoreOpcode = Ty == Type::FloatTy ? X86::FSTr32 : X86::FSTr64; - - if (TM.getTargetData().isLittleEndian()) { // fast path... - addDirectMem(BuildMI(BB, StoreOpcode,5), DestAddrReg).addReg(SrcReg); - return; - } - - // Allocate a temporary stack slot to transform the value into... - int FrameIdx = F->getFrameInfo()->CreateStackObject(Ty, TM.getTargetData()); - unsigned SrcAddrReg = makeAnotherReg(Type::UIntTy); - addFrameReference(BuildMI(BB, X86::LEAr32, 5, SrcAddrReg), FrameIdx); - - // Store the value into a temporary stack slot... - addDirectMem(BuildMI(BB, StoreOpcode, 5), SrcAddrReg).addReg(SrcReg); - - // Perform the bswaps 32 bits at a time... - unsigned TmpReg1 = makeAnotherReg(Type::UIntTy); - unsigned TmpReg2 = makeAnotherReg(Type::UIntTy); - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, TmpReg1), SrcAddrReg); - BuildMI(BB, X86::BSWAPr32, 1, TmpReg2).addReg(TmpReg1); - unsigned Offset = (Ty == Type::DoubleTy) << 2; - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - DestAddrReg, Offset).addReg(TmpReg2); - - if (Ty == Type::DoubleTy) { // Swap the other 32 bits of a double value... - TmpReg1 = makeAnotherReg(Type::UIntTy); - TmpReg2 = makeAnotherReg(Type::UIntTy); - - addRegOffset(BuildMI(BB, X86::MOVmr32, 4, TmpReg1), SrcAddrReg, 4); - BuildMI(BB, X86::BSWAPr32, 1, TmpReg2).addReg(TmpReg1); - unsigned Offset = (Ty == Type::DoubleTy) << 2; - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), DestAddrReg).addReg(TmpReg2); - } + static const unsigned Opcodes[] = { + X86::MOVmr8, X86::MOVmr16, X86::MOVmr32, X86::FLDr32 + }; + unsigned Opcode = Opcodes[Class]; + if (I.getType() == Type::DoubleTy) Opcode = X86::FLDr64; + addDirectMem(BuildMI(BB, Opcode, 4, DestReg), SrcAddrReg); } - /// visitStoreInst - Implement LLVM store instructions in terms of the x86 'mov' /// instruction. /// void ISel::visitStoreInst(StoreInst &I) { - bool isLittleEndian = TM.getTargetData().isLittleEndian(); - bool hasLongPointers = TM.getTargetData().getPointerSize() == 8; unsigned ValReg = getReg(I.getOperand(0)); unsigned AddressReg = getReg(I.getOperand(1)); + + const Type *ValTy = I.getOperand(0)->getType(); + unsigned Class = getClassB(ValTy); - unsigned Class = getClassB(I.getOperand(0)->getType()); - switch (Class) { - case cLong: - if (isLittleEndian) { - addDirectMem(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg).addReg(ValReg); - addRegOffset(BuildMI(BB, X86::MOVrm32, 1+4), - AddressReg, 4).addReg(ValReg+1); - } else { - unsigned T1 = makeAnotherReg(Type::IntTy); - unsigned T2 = makeAnotherReg(Type::IntTy); - EmitByteSwap(T1, ValReg , cInt); - EmitByteSwap(T2, ValReg+1, cInt); - addDirectMem(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg).addReg(T2); - addRegOffset(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg, 4).addReg(T1); - } - return; - case cFP: - doFPStore(I.getOperand(0)->getType(), AddressReg, ValReg); + if (Class == cLong) { + addDirectMem(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg).addReg(ValReg); + addRegOffset(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg,4).addReg(ValReg+1); return; - case cInt: case cShort: case cByte: - break; // Integers of various sizes handled below - default: assert(0 && "Unknown memory class!"); - } - - if (!isLittleEndian && hasLongPointers && - isa(I.getOperand(0)->getType())) { - unsigned R = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDri32, 2, R).addReg(AddressReg).addZImm(4); - AddressReg = R; } - if (!isLittleEndian && Class != cByte) { - unsigned R = makeAnotherReg(I.getOperand(0)->getType()); - EmitByteSwap(R, ValReg, Class); - ValReg = R; - } - - static const unsigned Opcode[] = { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32 }; - addDirectMem(BuildMI(BB, Opcode[Class], 1+4), AddressReg).addReg(ValReg); + static const unsigned Opcodes[] = { + X86::MOVrm8, X86::MOVrm16, X86::MOVrm32, X86::FSTr32 + }; + unsigned Opcode = Opcodes[Class]; + if (ValTy == Type::DoubleTy) Opcode = X86::FSTr64; + addDirectMem(BuildMI(BB, Opcode, 1+4), AddressReg).addReg(ValReg); }