diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 585fc5ea841..35c7df9b2ac 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -51,6 +51,9 @@ namespace CallingConv { // (HiPE). HiPE = 11, + // WebKit JS - Calling convention for stack based JavaScript calls + WebKit_JS = 12, + // Target - This is the start of the target-specific calling conventions, // e.g. fastcall and thiscall on X86. FirstTargetCC = 64, diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 99bff45792c..1f81800053c 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -559,6 +559,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(intel_ocl_bicc); KEYWORD(x86_64_sysvcc); KEYWORD(x86_64_win64cc); + KEYWORD(webkit_jscc); KEYWORD(cc); KEYWORD(c); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 74c0ea4af52..66136521159 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1349,6 +1349,7 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'spir_kernel' /// ::= 'x86_64_sysvcc' /// ::= 'x86_64_win64cc' +/// ::= 'webkit_jscc' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1371,6 +1372,7 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break; case lltok::kw_x86_64_win64cc: CC = CallingConv::X86_64_Win64; break; + case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index e1382fdb597..c31883cfc02 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -92,6 +92,7 @@ namespace lltok { kw_ptx_kernel, kw_ptx_device, kw_spir_kernel, kw_spir_func, kw_x86_64_sysvcc, kw_x86_64_win64cc, + kw_webkit_jscc, // Attributes: kw_attributes, diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index 2795b4cdd8f..f5c8d9fda43 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -151,6 +151,15 @@ def RetCC_X86_64_HiPE : CallingConv<[ CCIfType<[i64], CCAssignToReg<[R15, RBP, RAX, RDX]>> ]>; +// X86-64 WebKit_JS return-value convention. +def RetCC_X86_64_WebKit_JS : CallingConv<[ + // Promote all types to i64 + CCIfType<[i8, i16, i32], CCPromoteToType>, + + // Return: RAX + CCIfType<[i64], CCAssignToReg<[RAX]>> +]>; + // This is the root return-value convention for the X86-32 backend. def RetCC_X86_32 : CallingConv<[ // If FastCC, use RetCC_X86_32_Fast. @@ -167,6 +176,9 @@ def RetCC_X86_64 : CallingConv<[ // HiPE uses RetCC_X86_64_HiPE CCIfCC<"CallingConv::HiPE", CCDelegateTo>, + // Handle JavaScript calls. + CCIfCC<"CallingConv::WebKit_JS", CCDelegateTo>, + // Handle explicit CC selection CCIfCC<"CallingConv::X86_64_Win64", CCDelegateTo>, CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo>, @@ -329,6 +341,15 @@ def CC_X86_64_HiPE : CallingConv<[ CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>> ]>; +def CC_X86_64_WebKit_JS : CallingConv<[ + // Promote i8/i16 arguments to i32. + CCIfType<[i8, i16], CCPromoteToType>, + + // Integer/FP values are always stored in stack slots that are 8 bytes in size + // and 8-byte aligned. + CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>> +]>; + //===----------------------------------------------------------------------===// // X86 C Calling Convention //===----------------------------------------------------------------------===// @@ -520,6 +541,7 @@ def CC_X86_32 : CallingConv<[ def CC_X86_64 : CallingConv<[ CCIfCC<"CallingConv::GHC", CCDelegateTo>, CCIfCC<"CallingConv::HiPE", CCDelegateTo>, + CCIfCC<"CallingConv::WebKit_JS", CCDelegateTo>, CCIfCC<"CallingConv::X86_64_Win64", CCDelegateTo>, CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo>, diff --git a/test/CodeGen/X86/patchpoint.ll b/test/CodeGen/X86/patchpoint.ll index 9226adfdaef..36cca84932d 100644 --- a/test/CodeGen/X86/patchpoint.ll +++ b/test/CodeGen/X86/patchpoint.ll @@ -42,6 +42,26 @@ entry: ret void } +; Test the webkit_jscc calling convention. +; Two arguments will be pushed on the stack. +; Return value in $rax. +define void @jscall_patchpoint_codegen(i64 %p1, i64 %p2, i64 %p3, i64 %p4) { +entry: +; CHECK-LABEL: _jscall_patchpoint_codegen: +; CHECK: Ltmp +; CHECK: movq %r{{.+}}, 8(%rsp) +; CHECK: movq %r{{.+}}, (%rsp) +; CHECK: movq $-559038736, %rax +; CHECK: Ltmp +; CHECK: callq *%rax +; CHECK: movq %rax, 8(%rsp) +; CHECK: callq + %resolveCall2 = inttoptr i64 -559038736 to i8* + %result = tail call webkit_jscc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 5, i32 12, i8* %resolveCall2, i32 2, i64 %p1, i64 %p2) + %resolveCall3 = inttoptr i64 -559038737 to i8* + tail call webkit_jscc void (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i32 6, i32 12, i8* %resolveCall3, i32 2, i64 %p1, i64 %result) + ret void +} declare void @llvm.experimental.stackmap(i32, i32, ...) declare void @llvm.experimental.patchpoint.void(i32, i32, i8*, i32, ...)