[WebAssembly] Codegen support for ISD::ExternalSymbol

llvm-svn: 254075
This commit is contained in:
Dan Gohman 2015-11-25 16:44:29 +00:00
parent 7bca3db8b9
commit 2c8fe6a428
5 changed files with 38 additions and 2 deletions

View File

@ -114,6 +114,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
computeRegisterProperties(Subtarget->getRegisterInfo());
setOperationAction(ISD::GlobalAddress, MVTPtr, Custom);
setOperationAction(ISD::ExternalSymbol, MVTPtr, Custom);
setOperationAction(ISD::JumpTable, MVTPtr, Custom);
for (auto T : {MVT::f32, MVT::f64}) {
@ -412,6 +413,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
return SDValue();
case ISD::GlobalAddress:
return LowerGlobalAddress(Op, DAG);
case ISD::ExternalSymbol:
return LowerExternalSymbol(Op, DAG);
case ISD::JumpTable:
return LowerJumpTable(Op, DAG);
case ISD::BR_JT:
@ -433,6 +436,16 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT));
}
SDValue WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
const auto *ES = cast<ExternalSymbolSDNode>(Op);
EVT VT = Op.getValueType();
assert(ES->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
DAG.getTargetExternalSymbol(ES->getSymbol(), VT));
}
SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
SelectionDAG &DAG) const {
// There's no need for a Wrapper node because we always incorporate a jump

View File

@ -125,8 +125,10 @@ def CONST_F64 : I<(outs F64:$res), (ins f64imm:$imm),
[(set F64:$res, fpimm:$imm)],
"f64.const\t$res, $imm">;
def : Pat<(i32 (WebAssemblywrapper tglobaladdr :$dst)),
(CONST_I32 tglobaladdr :$dst)>;
def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$dst)),
(CONST_I32 tglobaladdr:$dst)>;
def : Pat<(i32 (WebAssemblywrapper texternalsym:$dst)),
(CONST_I32 texternalsym:$dst)>;
def JUMP_TABLE : I<(outs I32:$dst), (ins tjumptable_op:$addr),
[(set I32:$dst, (WebAssemblywrapper tjumptable:$addr))],

View File

@ -34,6 +34,11 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
return Printer.getSymbol(MO.getGlobal());
}
MCSymbol *
WebAssemblyMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
@ -90,6 +95,9 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
break;
case MachineOperand::MO_ExternalSymbol:
MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
break;
}
OutMI.addOperand(MCOp);

View File

@ -44,6 +44,7 @@ public:
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
};
}

View File

@ -18,6 +18,18 @@ define i32 @foo() {
ret i32 %a
}
; CHECK-LABEL: call_memcpy:
; CHECK-NEXT: .param i32, i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.const $push0=, memcpy{{$}}
; CHECK-NEXT: call_indirect $pop0, $0, $1, $2{{$}}
; CHECK-NEXT: return $0{{$}}
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
ret i8* %p
}
; CHECK: .type g,@object
; CHECK: .align 2{{$}}
; CHECK-NEXT: g: