From 0ec587e26cd7e048b3150f89fa6d6245d5728cec Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 14 Apr 2013 01:33:32 +0000 Subject: [PATCH] Add target flags to SPARC address operands. SDNodes and MachineOperands get target flags representing the %hi() and %lo() assembly annotations that eventually become relocations. Also define flags to be used by the 64-bit code models. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179468 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h | 62 +++++++++++++++++++ lib/Target/Sparc/SparcISelLowering.cpp | 44 ++++++++----- lib/Target/Sparc/SparcISelLowering.h | 3 + 3 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h diff --git a/lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h b/lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h new file mode 100644 index 00000000000..aac0e8d74a8 --- /dev/null +++ b/lib/Target/Sparc/MCTargetDesc/SparcBaseInfo.h @@ -0,0 +1,62 @@ +//===-- SparcBaseInfo.h - Top level definitions for Sparc ---- --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions +// for the Sparc target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core code gen +// types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef SPARCBASEINFO_H +#define SPARCBASEINFO_H + +namespace llvm { + +/// SPII - This namespace holds target specific flags for instruction info. +namespace SPII { + +/// Target Operand Flags. Sparc specific TargetFlags for MachineOperands and +/// SDNodes. +enum TOF { + MO_NO_FLAG, + + // Extract the low 10 bits of an address. + // Assembler: %lo(addr) + MO_LO, + + // Extract bits 31-10 of an address. Only for sethi. + // Assembler: %hi(addr) or %lm(addr) + MO_HI, + + // Extract bits 43-22 of an adress. Only for sethi. + // Assembler: %h44(addr) + MO_H44, + + // Extract bits 21-12 of an address. + // Assembler: %m44(addr) + MO_M44, + + // Extract bits 11-0 of an address. + // Assembler: %l44(addr) + MO_L44, + + // Extract bits 63-42 of an address. Only for sethi. + // Assembler: %hh(addr) + MO_HH, + + // Extract bits 41-32 of an address. + // Assembler: %hm(addr) + MO_HM +}; + +} // end namespace SPII +} // end namespace llvm + +#endif diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index b985678c6f9..322f5735105 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -15,6 +15,7 @@ #include "SparcISelLowering.h" #include "SparcMachineFunctionInfo.h" #include "SparcTargetMachine.h" +#include "MCTargetDesc/SparcBaseInfo.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -1354,24 +1355,39 @@ static void LookThroughSetCC(SDValue &LHS, SDValue &RHS, } } +// Convert to a target node and set target flags. +SDValue SparcTargetLowering::withTargetFlags(SDValue Op, unsigned TF, + SelectionDAG &DAG) const { + if (const GlobalAddressSDNode *GA = dyn_cast(Op)) + return DAG.getTargetGlobalAddress(GA->getGlobal(), + GA->getDebugLoc(), + GA->getValueType(0), + GA->getOffset(), TF); + llvm_unreachable("Unhandled address SDNode"); +} + +// Split Op into high and low parts according to HiTF and LoTF. +// Return an ADD node combining the parts. +SDValue SparcTargetLowering::makeHiLoPair(SDValue Op, + unsigned HiTF, unsigned LoTF, + SelectionDAG &DAG) const { + DebugLoc DL = Op.getDebugLoc(); + EVT VT = Op.getValueType(); + SDValue Hi = DAG.getNode(SPISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); + SDValue Lo = DAG.getNode(SPISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); + return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); +} + SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - const GlobalValue *GV = cast(Op)->getGlobal(); - // FIXME there isn't really any debug info here - DebugLoc dl = Op.getDebugLoc(); - SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32); - SDValue Hi = DAG.getNode(SPISD::Hi, dl, MVT::i32, GA); - SDValue Lo = DAG.getNode(SPISD::Lo, dl, MVT::i32, GA); - + SDValue HiLo = makeHiLoPair(Op, SPII::MO_HI, SPII::MO_LO, DAG); if (getTargetMachine().getRelocationModel() != Reloc::PIC_) - return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi); + return HiLo; - SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, dl, - getPointerTy()); - SDValue RelAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi); - SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, - GlobalBase, RelAddr); - return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), + DebugLoc DL = Op.getDebugLoc(); + SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, getPointerTy()); + SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, getPointerTy(), GlobalBase, HiLo); + return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), AbsAddr, MachinePointerInfo(), false, false, false, 0); } diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 8a50f6890a0..3ccdf7a973d 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/lib/Target/Sparc/SparcISelLowering.h @@ -121,6 +121,9 @@ namespace llvm { SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; unsigned getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const; + SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; + SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, + SelectionDAG &DAG) const; }; } // end namespace llvm -- 2.34.1