Skip to content

Commit d6ce440

Browse files
committed
[Mips] Handle declspec(dllimport) on mipsel-windows-* triples
1 parent 40f4c9a commit d6ce440

File tree

7 files changed

+128
-4
lines changed

7 files changed

+128
-4
lines changed

llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ namespace MipsII {
9292
MO_CALL_LO16,
9393

9494
/// Helper operand used to generate R_MIPS_JALR
95-
MO_JALR
95+
MO_JALR,
96+
97+
/// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the
98+
/// reference is actually to the "__imp_FOO" symbol. This is used for
99+
/// dllimport linkage on windows.
100+
MO_DLLIMPORT = 0x20,
96101
};
97102

98103
enum {

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,14 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
21052105
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
21062106
const GlobalValue *GV = N->getGlobal();
21072107

2108+
if (GV->hasDLLImportStorageClass()) {
2109+
assert(Subtarget.isTargetWindows() &&
2110+
"Windows is the only supported COFF target");
2111+
return getDllimportVariable(
2112+
N, SDLoc(N), Ty, DAG,
2113+
DAG.getEntryNode(), MachinePointerInfo::getGOT(DAG.getMachineFunction()));
2114+
}
2115+
21082116
if (!isPositionIndependent()) {
21092117
const MipsTargetObjectFile *TLOF =
21102118
static_cast<const MipsTargetObjectFile *>(
@@ -3460,7 +3468,13 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
34603468
}
34613469

34623470
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
3463-
if (IsPIC) {
3471+
if (Subtarget.isTargetCOFF() && G->getGlobal()->hasDLLImportStorageClass()) {
3472+
assert(Subtarget.isTargetWindows() &&
3473+
"Windows is the only supported COFF target");
3474+
auto PtrInfo = MachinePointerInfo();
3475+
Callee = DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(G, SDLoc(G), Ty, DAG),
3476+
PtrInfo);
3477+
} else if (IsPIC) {
34643478
const GlobalValue *Val = G->getGlobal();
34653479
InternalLinkage = Val->hasInternalLinkage();
34663480

llvm/lib/Target/Mips/MipsISelLowering.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,32 @@ class TargetRegisterClass;
485485
DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));
486486
}
487487

488+
// This method creates the following nodes, which are necessary for
489+
// loading a dllimported symbol:
490+
//
491+
// (lw (add (shl(%high(sym), 16), %low(sym)))
492+
template <class NodeTy>
493+
SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const {
494+
SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);
495+
SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);
496+
return DAG.getNode(ISD::ADD, DL, Ty,
497+
DAG.getNode(MipsISD::Lo, DL, Ty, Lo),
498+
DAG.getNode(MipsISD::Hi, DL, Ty, Hi));
499+
}
500+
501+
// This method creates the following nodes, which are necessary for
502+
// loading a dllimported global variable:
503+
//
504+
// (lw (lw (add (shl(%high(sym), 16), %low(sym))))
505+
template <class NodeTy>
506+
SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
507+
SDValue Chain,
508+
const MachinePointerInfo &PtrInfo) const {
509+
return DAG.getLoad(Ty, DL, Chain,
510+
getDllimportSymbol(N, DL, Ty, DAG),
511+
PtrInfo);
512+
}
513+
488514
/// This function fills Ops, which is the list of operands that will later
489515
/// be used when a function call node is created. It also generates
490516
/// copyToReg nodes to set up argument registers.

llvm/lib/Target/Mips/MipsMCInstLower.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/CodeGen/MachineBasicBlock.h"
1919
#include "llvm/CodeGen/MachineInstr.h"
2020
#include "llvm/CodeGen/MachineOperand.h"
21+
#include "llvm/MC/MCContext.h"
2122
#include "llvm/MC/MCExpr.h"
2223
#include "llvm/MC/MCInst.h"
2324
#include "llvm/Support/ErrorHandling.h"
@@ -38,8 +39,16 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
3839
MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
3940
bool IsGpOff = false;
4041
const MCSymbol *Symbol;
42+
SmallString<128> Name;
43+
unsigned TargetFlags = MO.getTargetFlags();
4144

42-
switch(MO.getTargetFlags()) {
45+
if (TargetFlags & MipsII::MO_DLLIMPORT) {
46+
// Handle dllimport linkage
47+
Name += "__imp_";
48+
TargetFlags &= ~MipsII::MO_DLLIMPORT;
49+
}
50+
51+
switch(TargetFlags) {
4352
default:
4453
llvm_unreachable("Invalid target flag!");
4554
case MipsII::MO_NO_FLAG:
@@ -125,7 +134,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
125134
break;
126135

127136
case MachineOperand::MO_GlobalAddress:
128-
Symbol = AsmPrinter.getSymbol(MO.getGlobal());
137+
AsmPrinter.getNameWithPrefix(Name, MO.getGlobal());
138+
Symbol = Ctx->getOrCreateSymbol(Name);
129139
Offset += MO.getOffset();
130140
break;
131141

llvm/lib/Target/Mips/MipsSubtarget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
300300
return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32();
301301
}
302302
bool isSingleFloat() const { return IsSingleFloat; }
303+
bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
303304
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
304305
bool hasVFPU() const { return HasVFPU; }
305306
bool inMips16Mode() const { return InMips16Mode; }
@@ -355,6 +356,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
355356
bool os16() const { return Os16; }
356357

357358
bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
359+
bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
358360

359361
bool isXRaySupported() const override { return true; }
360362

llvm/test/CodeGen/Mips/dllimport.ll

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; RUN: llc -mtriple mipsel-windows < %s | FileCheck %s
2+
3+
@Var1 = external dllimport global i32
4+
@Var2 = available_externally dllimport unnamed_addr constant i32 1
5+
6+
declare dllimport void @fun()
7+
8+
define available_externally dllimport void @inline1() {
9+
ret void
10+
}
11+
12+
define available_externally dllimport void @inline2() alwaysinline {
13+
ret void
14+
}
15+
16+
declare void @dummy(...)
17+
18+
define void @use() nounwind {
19+
; CHECK: lui $1, %hi(__imp_fun)
20+
; CHECK: addiu $1, $1, %lo(__imp_fun)
21+
; CHECK: lw $25, 0($1)
22+
; CHECK: jalr $25
23+
call void @fun()
24+
25+
; CHECK: lui $1, %hi(__imp_inline1)
26+
; CHECK: addiu $1, $1, %lo(__imp_inline1)
27+
; CHECK: lw $25, 0($1)
28+
; CHECK: jalr $25
29+
call void @inline1()
30+
31+
; CHECK: lui $1, %hi(__imp_inline2)
32+
; CHECK: addiu $1, $1, %lo(__imp_inline2)
33+
; CHECK: lw $25, 0($1)
34+
; CHECK: jalr $25
35+
call void @inline2()
36+
37+
; CHECK: lui $1, %hi(__imp_Var2)
38+
; CHECK: addiu $1, $1, %lo(__imp_Var2)
39+
; CHECK: lw $1, 0($1)
40+
; CHECK: lw $5, 0($1)
41+
; CHECK: lui $1, %hi(__imp_Var1)
42+
; CHECK: addiu $1, $1, %lo(__imp_Var1)
43+
; CHECK: lw $1, 0($1)
44+
; CHECK: lw $4, 0($1)
45+
%1 = load i32, ptr @Var1
46+
%2 = load i32, ptr @Var2
47+
call void(...) @dummy(i32 %1, i32 %2)
48+
49+
ret void
50+
}
51+
52+
; CHECK: fp:
53+
; CHECK-NEXT: .long fun
54+
@fp = constant ptr @fun
55+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llc -mtriple mipsel-windows -filetype obj < %s | llvm-objdump --reloc - | FileCheck %s
2+
3+
declare dllimport void @fun()
4+
5+
define void @use() nounwind {
6+
; CHECK: 00000008 IMAGE_REL_MIPS_REFHI __imp_fun
7+
; CHECK: 00000008 IMAGE_REL_MIPS_PAIR .text
8+
; CHECK: 0000000c IMAGE_REL_MIPS_REFLO __imp_fun
9+
call void() @fun()
10+
11+
ret void
12+
}

0 commit comments

Comments
 (0)