Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Unified Diff: lib/Target/ARM/ARMISelLowering.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Target/ARM/ARMISelLowering.h ('k') | lib/Target/ARM/ARMInstrInfo.td » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Target/ARM/ARMISelLowering.cpp
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index fe84f0d4f94212ff9118736b63d9282a9b9c379e..337a4ad62429470e0d27e9ea1f7d357fcfa358d4 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -49,6 +49,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
#include <utility>
+
using namespace llvm;
#define DEBUG_TYPE "arm-isel"
@@ -67,6 +68,18 @@ ARMInterworking("arm-interworking", cl::Hidden,
cl::desc("Enable / disable ARM interworking (for debugging only)"),
cl::init(true));
+// @LOCALMOD-START
+// PNaCl's build of compiler-rt does not define __aeabi_* functions for ARM
+// yet. For Non-SFI NaCl, where we don't use "nacl" in the target triple,
+// we use the following option to turn off use of the __aeabi_* functions.
+// TODO(mseaborn): In the longer term, it would be cleaner to change the
+// compiler-rt build to define __aeabi_* functions.
+cl::opt<bool>
+llvm::EnableARMAEABIFunctions("arm-enable-aeabi-functions",
+ cl::desc("Allow using ARM __aeabi_* functions in generated code"),
+ cl::init(true));
+// @LOCALMOD-END
+
namespace {
class ARMCCState : public CCState {
public:
@@ -247,8 +260,10 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM)
setLibcallName(RTLIB::SRL_I128, nullptr);
setLibcallName(RTLIB::SRA_I128, nullptr);
+ // @LOCALMOD: use standard names and calling conventions for pnacl
if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() &&
- !Subtarget->isTargetWindows()) {
+ !Subtarget->isTargetWindows() && !Subtarget->isTargetNaCl() &&
+ EnableARMAEABIFunctions) {
static const struct {
const RTLIB::Libcall Op;
const char * const Name;
@@ -735,7 +750,11 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM)
setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
-
+ // @LOCALMOD-START
+ if (!Subtarget->useInlineJumpTables())
+ setOperationAction(ISD::JumpTable, MVT::i32, Custom);
+ // @LOCALMOD-END
+
setOperationAction(ISD::TRAP, MVT::Other, Legal);
// Use the default implementation.
@@ -749,8 +768,22 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM)
if (!Subtarget->isTargetMachO()) {
// Non-MachO platforms may return values in these registers via the
// personality function.
- setExceptionPointerRegister(ARM::R0);
- setExceptionSelectorRegister(ARM::R1);
+ // @LOCALMOD-START
+ if (Subtarget->isTargetNaCl()) {
+ // we use the first caller saved regs here
+ // c.f.: llvm-gcc/llvm-gcc-4.2/gcc/unwind-dw2.c::uw_install_context
+ // NOTE: these are related to the _Unwind_PNaClSetResult{0,1} functions
+ setExceptionPointerRegister(ARM::R4);
+ setExceptionSelectorRegister(ARM::R5);
+
+ setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
+
+ setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
+ } else {
+ setExceptionPointerRegister(ARM::R0);
+ setExceptionSelectorRegister(ARM::R1);
+ }
+ // @LOCALMOD-END
}
if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment())
@@ -839,8 +872,12 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM)
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
- setOperationAction(ISD::BR_JT, MVT::Other, Custom);
-
+ // @LOCALMOD-START
+ //setOperationAction(ISD::BR_JT, MVT::Other, Custom);
+ setOperationAction(ISD::BR_JT, MVT::Other,
+ Subtarget->useInlineJumpTables() ? Custom : Expand);
+ // @LOCALMOD-END
+
// We don't support sin/cos/fmod/copysign/pow
setOperationAction(ISD::FSIN, MVT::f64, Expand);
setOperationAction(ISD::FSIN, MVT::f32, Expand);
@@ -1006,6 +1043,10 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::Wrapper: return "ARMISD::Wrapper";
case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC";
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
+ // @LOCALMOD-START
+ case ARMISD::WrapperJT2: return "ARMISD::WrapperJT2";
+ case ARMISD::EH_RETURN: return "ARMISD::EH_RETURN";
+ // @LOCALMOD-END
case ARMISD::CALL: return "ARMISD::CALL";
case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED";
case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK";
@@ -2384,7 +2425,14 @@ static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
}
unsigned ARMTargetLowering::getJumpTableEncoding() const {
- return MachineJumpTableInfo::EK_Inline;
+ // @LOCALMOD-BEGIN
+ if (Subtarget->useInlineJumpTables()) {
+ return MachineJumpTableInfo::EK_Inline;
+ } else {
+ // TODO: Find a better way to call the super-class.
+ return TargetLowering::getJumpTableEncoding();
+ }
+ // @LOCALMOD-END
}
SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
@@ -2417,12 +2465,69 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
}
+// @LOCALMOD-START
+// more conventional jumptable implementation
+SDValue ARMTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
+ assert(!Subtarget->useInlineJumpTables() &&
+ "inline jump tables not custom lowered");
+ const SDLoc dl(Op);
+ EVT PTy = getPointerTy();
+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+ SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
+ return DAG.getNode(ARMISD::WrapperJT2, dl, MVT::i32, JTI);
+}
+// @LOCALMOD-END
+
// Lower ISD::GlobalTLSAddress using the "general dynamic" model
SDValue
ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG) const {
SDLoc dl(GA);
EVT PtrVT = getPointerTy();
+ // @LOCALMOD-BEGIN
+ SDValue Chain;
+ SDValue Argument;
+
+ if (!Subtarget->useConstIslands()) {
+ // With constant islands "disabled" (moved to rodata), this constant pool
+ // entry is no longer in text, and simultaneous PC relativeness
+ // and CP Addr relativeness is no longer expressible.
+ // So, instead of having:
+ //
+ // .LCPI12_0:
+ // .long var(tlsgd)-((.LPC12_0+8) - .)
+ // ...
+ // ldr r2, .LCPI12_0
+ // .LPC12_0:
+ // add r0, pc, r2
+ //
+ // we have:
+ //
+ // .LCPI12_0:
+ // .long var(tlsgd)
+ // ...
+ // // get addr of .LCPI12_0 into r2
+ // ldr r0, [r2]
+ // add r0, r2, r0
+ // (1) No longer subtracting pc, so no longer adding that back
+ // (2) Not adding "." in the CP entry, so adding it via instructions.
+ //
+ unsigned char PCAdj = 0;
+ MachineFunction &MF = DAG.getMachineFunction();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
+ ARMConstantPoolValue *CPV =
+ ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
+ ARMCP::CPValue, PCAdj, ARMCP::TLSGD,
+ false);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
+ Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
+ MachinePointerInfo::getConstantPool(),
+ false, false, false, 0);
+ Chain = Argument.getValue(1);
+ Argument = DAG.getNode(ISD::ADD, dl, PtrVT, Argument, CPAddr);
+ } else { // sort of @LOCALMOD-END
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
@@ -2430,15 +2535,16 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
ARMConstantPoolValue *CPV =
ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
- SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ /*SDValue*/ Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); // @LOCALMOD
Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument,
MachinePointerInfo::getConstantPool(),
false, false, false, 0);
- SDValue Chain = Argument.getValue(1);
+ /*SDValue*/ Chain = Argument.getValue(1); // @LOCALMOD
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
+ } // @LOCALMOD-END
// call __tls_get_addr.
ArgListTy Args;
@@ -2476,25 +2582,49 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
- // Initial exec model.
- unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
- ARMConstantPoolValue *CPV =
+
+ // @LOCALMOD-BEGIN
+ if (!Subtarget->useConstIslands()) {
+ // Similar to change to LowerToTLSGeneralDynamicModel, and
+ // for the same reason.
+ unsigned char PCAdj = 0;
+ ARMConstantPoolValue *CPV =
+ ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
+ ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF,
+ false);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
+ Offset = DAG.getLoad(PtrVT, dl, Chain, CPAddr,
+ MachinePointerInfo::getConstantPool(),
+ false, false, false, 0);
+ Chain = Offset.getValue(1);
+
+ Offset = DAG.getNode(ISD::ADD, dl, PtrVT, Offset, CPAddr);
+
+ Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
+ MachinePointerInfo::getConstantPool(),
+ false, false, false, 0);
+ } else { // sort of @LOCALMOD-END (indentation)
+ // Initial exec model.
+ unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
+ ARMConstantPoolValue *CPV =
ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF,
true);
- Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
- Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
- Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- MachinePointerInfo::getConstantPool(),
- false, false, false, 0);
- Chain = Offset.getValue(1);
+ Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
+ Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
+ MachinePointerInfo::getConstantPool(),
+ false, false, false, 0);
+ Chain = Offset.getValue(1);
- SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
- Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
+ SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
+ Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
- Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- MachinePointerInfo::getConstantPool(),
- false, false, false, 0);
+ Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
+ MachinePointerInfo::getConstantPool(),
+ false, false, false, 0);
+ } // @LOCALMOD-END
} else {
// local exec model
assert(model == TLSModel::LocalExec);
@@ -2634,6 +2764,44 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op,
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
EVT PtrVT = getPointerTy();
SDLoc dl(Op);
+
+ // @LOCALMOD-BEGIN
+ if (!Subtarget->useConstIslands()) {
+ // With constant islands "disabled" (moved to rodata), the constant pool
+ // entry is no longer in text, and the PC relativeness is
+ // no longer expressible.
+ //
+ // Instead of having:
+ //
+ // .LCPI12_0:
+ // .long _GLOBAL_OFFSET_TABLE_-(.LPC12_0+8)
+ // ...
+ // ldr r2, .LCPI12_0
+ // .LPC12_0:
+ // add r0, pc, r2
+ //
+ // Things to try:
+ // (1) get the address of the GOT through a pc-relative MOVW / MOVT.
+ //
+ // movw r0, :lower16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8)
+ // movt r0, :upper16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8)
+ // .LPC12_0:
+ // add r0, pc, r0
+ //
+ // (2) Make the constant pool entry relative to its own location
+ //
+ // .LCPI12_0:
+ // .long _GLOBAL_OFFSET_TABLE_-.
+ // ...
+ // // get address of LCPI12_0 into r0 (possibly 3 instructions for PIC)
+ // ldr r1, [r0]
+ // add r1, r0, r1
+ //
+ // We will try (1) for now, since (2) takes about 3 more instructions
+ // (and one of them is a load).
+ return DAG.getNode(ARMISD::WrapperGOT, dl, MVT::i32);
+ }
+ // @LOCALMOD-END
unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMConstantPoolValue *CPV =
ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_",
@@ -2675,6 +2843,7 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
"RBIT intrinsic must have i32 type!");
return DAG.getNode(ARMISD::RBIT, dl, MVT::i32, Op.getOperand(1));
}
+ case Intrinsic::nacl_read_tp: // @LOCALMOD
case Intrinsic::arm_thread_pointer: {
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
@@ -6078,6 +6247,38 @@ static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) {
DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
}
+// @LOCALMOD-START
+// An EH_RETURN is the result of lowering llvm.eh.return.i32 which in turn is
+// generated from __builtin_eh_return (offset, handler)
+// The effect of this is to adjust the stack pointer by "offset"
+// and then branch to "handler".
+SDValue ARMTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
+ const {
+ SDValue Chain = Op.getOperand(0);
+ SDValue Offset = Op.getOperand(1);
+ SDValue Handler = Op.getOperand(2);
+ SDLoc dl(Op);
+
+ // Store stack offset in R2, jump target in R3, dummy return value in R0
+ // The dummy return value is needed to make the use-def chains happy,
+ // because the EH_RETURN instruction uses the isReturn attribute, which
+ // means preceding code needs to define the return register (R0 on ARM).
+ // http://code.google.com/p/nativeclient/issues/detail?id=2643
+ unsigned OffsetReg = ARM::R2;
+ unsigned AddrReg = ARM::R3;
+ unsigned ReturnReg = ARM::R0;
+ Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
+ Chain = DAG.getCopyToReg(Chain, dl, AddrReg, Handler);
+ Chain = DAG.getCopyToReg(Chain, dl, ReturnReg, DAG.getIntPtrConstant(0));
+ return DAG.getNode(ARMISD::EH_RETURN, dl,
+ MVT::Other,
+ Chain,
+ DAG.getRegister(OffsetReg, MVT::i32),
+ DAG.getRegister(AddrReg, getPointerTy()));
+}
+// @LOCALMOD-END
+
+
static SDValue
LowerSDIV_v4i8(SDValue X, SDValue Y, SDLoc dl, SelectionDAG &DAG) {
// Convert to float
@@ -6390,6 +6591,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
default: llvm_unreachable("Don't know how to custom lower this!");
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
+ case ISD::JumpTable: return LowerJumpTable(Op, DAG); // @LOCALMOD
case ISD::GlobalAddress:
switch (Subtarget->getTargetTriple().getObjectFormat()) {
default: llvm_unreachable("unknown object format");
@@ -6415,6 +6617,17 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
+ // @LOCALMOD-START
+ // The exact semantics of this ISD are not completely clear.
+ // LLVM seems to always point the fp after the push ra and the old fp, i.e.
+ // two register slots after the beginning of the stack frame.
+ // It is not clear what happens when there is no frame pointer but
+ // but llvm unlike gcc seems to always force one when this node is
+ // encountered.
+ case ISD::FRAME_TO_ARGS_OFFSET: return DAG.getIntPtrConstant(2*4);
+ case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
+ // @LOCALMOD-END
+
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
@@ -10305,6 +10518,15 @@ ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
if (Subtarget->isThumb1Only())
return false;
+ // @LOCALMOD-START
+ // Avoid two reg addressing mode for loads and stores
+ const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() &&
+ (N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE);
+ if (restrict_addressing_modes_for_nacl) {
+ return false;
+ }
+ // @LOCALMOD-END
+
EVT VT;
SDValue Ptr;
bool isSEXTLoad = false;
@@ -10343,7 +10565,14 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
SelectionDAG &DAG) const {
if (Subtarget->isThumb1Only())
return false;
-
+ // @LOCALMOD-START
+ // Avoid two reg addressing mode for loads and stores
+ const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() &&
+ (N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE);
+ if (restrict_addressing_modes_for_nacl) {
+ return false;
+ }
+ // @LOCALMOD-END
EVT VT;
SDValue Ptr;
bool isSEXTLoad = false;
« no previous file with comments | « lib/Target/ARM/ARMISelLowering.h ('k') | lib/Target/ARM/ARMInstrInfo.td » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698