<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191130] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191130">191130</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2015-10-15 12:54:02 -0700 (Thu, 15 Oct 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add MASM_PROBE support for ARM64.
https://bugs.webkit.org/show_bug.cgi?id=150128
Reviewed by Michael Saboff.
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/ARM64Assembler.h:
- Convert the ARM64 registers enum list into a macro list so that we can use
it elsewhere e.g. to declare fields in the probe CPUState.
Also de-tabbed the contents of the ARM64Registers namespace since the enum
list change touches almost all of it anyway. This reduces the amount of
complaints from the style checker.
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::CPUState::registerName):
(JSC::AbstractMacroAssembler::CPUState::registerValue):
- Change CPUState methods to allow for registers ID that do not map to one of
its fields. This is needed because ARM64's registers include aliases for some
register names. The CPUState will not allocate separate storage for the
aliases.
* assembler/MacroAssemblerARM64.cpp: Added.
(JSC::arm64ProbeTrampoline):
- Unlike the probe mechanism for other CPUs, the ARM64 implementation does not
allow the probe function to modify the sp and pc registers. We insert this
wrapper function between ctiMasmProbeTrampoline() and the user's probe function
so that we can check if the user tried to modify sp and pc. If so, we will
print an error message so that we can alert the user that we don't support
that on ARM64.
See the comment in ctiMasmProbeTrampoline() in JITStubsARM64.h for details
on why we cannot support sp and pc modifications by the probe function.
(JSC::MacroAssemblerARM64::probe):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::repatchCall):
(JSC::MacroAssemblerARM64::makeBranch):
* jit/JITStubs.cpp:
* jit/JITStubsARM64.h: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerARM64Assemblerh">trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh">trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubscpp">trunk/Source/JavaScriptCore/jit/JITStubs.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64cpp">trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubsARM64h">trunk/Source/JavaScriptCore/jit/JITStubsARM64.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -1,5 +1,48 @@
</span><span class="cx"> 2015-10-15 Mark Lam <mark.lam@apple.com>
</span><span class="cx">
</span><ins>+ Add MASM_PROBE support for ARM64.
+ https://bugs.webkit.org/show_bug.cgi?id=150128
+
+ Reviewed by Michael Saboff.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/ARM64Assembler.h:
+ - Convert the ARM64 registers enum list into a macro list so that we can use
+ it elsewhere e.g. to declare fields in the probe CPUState.
+ Also de-tabbed the contents of the ARM64Registers namespace since the enum
+ list change touches almost all of it anyway. This reduces the amount of
+ complaints from the style checker.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::CPUState::registerName):
+ (JSC::AbstractMacroAssembler::CPUState::registerValue):
+ - Change CPUState methods to allow for registers ID that do not map to one of
+ its fields. This is needed because ARM64's registers include aliases for some
+ register names. The CPUState will not allocate separate storage for the
+ aliases.
+
+ * assembler/MacroAssemblerARM64.cpp: Added.
+ (JSC::arm64ProbeTrampoline):
+ - Unlike the probe mechanism for other CPUs, the ARM64 implementation does not
+ allow the probe function to modify the sp and pc registers. We insert this
+ wrapper function between ctiMasmProbeTrampoline() and the user's probe function
+ so that we can check if the user tried to modify sp and pc. If so, we will
+ print an error message so that we can alert the user that we don't support
+ that on ARM64.
+
+ See the comment in ctiMasmProbeTrampoline() in JITStubsARM64.h for details
+ on why we cannot support sp and pc modifications by the probe function.
+
+ (JSC::MacroAssemblerARM64::probe):
+
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::repatchCall):
+ (JSC::MacroAssemblerARM64::makeBranch):
+ * jit/JITStubs.cpp:
+ * jit/JITStubsARM64.h: Added.
+
+2015-10-15 Mark Lam <mark.lam@apple.com>
+
</ins><span class="cx"> Fix some typos in comments.
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=150181
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -1792,6 +1792,8 @@
</span><span class="cx">                 FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
</span><span class="cx">                 FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                FEB137551BB0C6AD00CD5100 /* JITStubsARM64.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB137541BB0C68A00CD5100 /* JITStubsARM64.h */; settings = {ASSET_TAGS = (); }; };
+                FEB137571BB11EF900CD5100 /* MacroAssemblerARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */; settings = {ASSET_TAGS = (); }; };
</ins><span class="cx">                 FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEB51F6B1A97B688001F921C /* Regress141809.mm */; };
</span><span class="cx">                 FEB58C14187B8B160098EF0B /* ErrorHandlingScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */; };
</span><span class="cx">                 FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB58C13187B8B160098EF0B /* ErrorHandlingScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3725,6 +3727,8 @@
</span><span class="cx">                 FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITSubGenerator.h; sourceTree = "<group>"; };
</span><span class="cx">                 FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; };
</span><span class="cx">                 FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; };
</span><ins>+                FEB137541BB0C68A00CD5100 /* JITStubsARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM64.h; sourceTree = "<group>"; };
+                FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARM64.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 FEB51F6A1A97B688001F921C /* Regress141809.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Regress141809.h; path = API/tests/Regress141809.h; sourceTree = "<group>"; };
</span><span class="cx">                 FEB51F6B1A97B688001F921C /* Regress141809.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Regress141809.mm; path = API/tests/Regress141809.mm; sourceTree = "<group>"; };
</span><span class="cx">                 FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorHandlingScope.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -4204,6 +4208,7 @@
</span><span class="cx">                                 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */,
</span><span class="cx">                                 14A6581A0F4E36F4000150FD /* JITStubs.h */,
</span><span class="cx">                                 FEF6835A174343CC00A32E25 /* JITStubsARM.h */,
</span><ins>+                                FEB137541BB0C68A00CD5100 /* JITStubsARM64.h */,
</ins><span class="cx">                                 FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */,
</span><span class="cx">                                 FEF6835D174343CC00A32E25 /* JITStubsX86.h */,
</span><span class="cx">                                 FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */,
</span><span class="lines">@@ -5576,6 +5581,7 @@
</span><span class="cx">                                 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
</span><span class="cx">                                 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */,
</span><span class="cx">                                 86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */,
</span><ins>+                                FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */,
</ins><span class="cx">                                 8640923C156EED3B00566CB2 /* MacroAssemblerARM64.h */,
</span><span class="cx">                                 A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */,
</span><span class="cx">                                 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */,
</span><span class="lines">@@ -6358,6 +6364,7 @@
</span><span class="cx">                                 0FEA0A241709606900BB722C /* FTLIntrinsicRepository.h in Headers */,
</span><span class="cx">                                 0FEA0A0E170513DB00BB722C /* FTLJITCode.h in Headers */,
</span><span class="cx">                                 A78A9781179738D5009DF744 /* FTLJITFinalizer.h in Headers */,
</span><ins>+                                FEB137551BB0C6AD00CD5100 /* JITStubsARM64.h in Headers */,
</ins><span class="cx">                                 0F6B1CB6185FC9E900845D97 /* FTLJSCall.h in Headers */,
</span><span class="cx">                                 0FD120301A8AED12000F5280 /* FTLJSCallBase.h in Headers */,
</span><span class="cx">                                 0FD120341A8C85BD000F5280 /* FTLJSCallVarargs.h in Headers */,
</span><span class="lines">@@ -7487,6 +7494,7 @@
</span><span class="cx">                                 0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
</span><span class="cx">                                 147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
</span><span class="cx">                                 0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
</span><ins>+                                FEB137571BB11EF900CD5100 /* MacroAssemblerARM64.cpp in Sources */,
</ins><span class="cx">                                 52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */,
</span><span class="cx">                                 0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */,
</span><span class="cx">                                 14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerARM64Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -388,91 +388,124 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> namespace ARM64Registers {
</span><del>- typedef enum {
- // Parameter/result registers
- x0,
- x1,
- x2,
- x3,
- x4,
- x5,
- x6,
- x7,
- // Indirect result location register
- x8,
- // Temporary registers
- x9,
- x10,
- x11,
- x12,
- x13,
- x14,
- x15,
- // Intra-procedure-call scratch registers (temporary)
- x16, ip0 = x16,
- x17, ip1 = x17,
- // Platform Register (temporary)
- x18,
- // Callee-saved
- x19,
- x20,
- x21,
- x22,
- x23,
- x24,
- x25,
- x26,
- x27,
- x28,
- // Special
- x29, fp = x29,
- x30, lr = x30,
- sp,
- zr = 0x3f,
- } RegisterID;
</del><span class="cx">
</span><del>- typedef enum {
- // Parameter/result registers
- q0,
- q1,
- q2,
- q3,
- q4,
- q5,
- q6,
- q7,
- // Callee-saved (up to 64-bits only!)
- q8,
- q9,
- q10,
- q11,
- q12,
- q13,
- q14,
- q15,
- // Temporary registers
- q16,
- q17,
- q18,
- q19,
- q20,
- q21,
- q22,
- q23,
- q24,
- q25,
- q26,
- q27,
- q28,
- q29,
- q30,
- q31,
- } FPRegisterID;
</del><ins>+#define FOR_EACH_CPU_REGISTER(V) \
+ FOR_EACH_CPU_GPREGISTER(V) \
+ FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+ FOR_EACH_CPU_FPREGISTER(V)
</ins><span class="cx">
</span><del>- static constexpr bool isSp(RegisterID reg) { return reg == sp; }
- static constexpr bool isZr(RegisterID reg) { return reg == zr; }
-}
</del><ins>+// The following are defined as pairs of the following value:
+// 1. type of the storage needed to save the register value by the JIT probe.
+// 2. name of the register.
+#define FOR_EACH_CPU_GPREGISTER(V) \
+ /* Parameter/result registers */ \
+ V(void*, x0) \
+ V(void*, x1) \
+ V(void*, x2) \
+ V(void*, x3) \
+ V(void*, x4) \
+ V(void*, x5) \
+ V(void*, x6) \
+ V(void*, x7) \
+ /* Indirect result location register */ \
+ V(void*, x8) \
+ /* Temporary registers */ \
+ V(void*, x9) \
+ V(void*, x10) \
+ V(void*, x11) \
+ V(void*, x12) \
+ V(void*, x13) \
+ V(void*, x14) \
+ V(void*, x15) \
+ /* Intra-procedure-call scratch registers (temporary) */ \
+ V(void*, x16) \
+ V(void*, x17) \
+ /* Platform Register (temporary) */ \
+ V(void*, x18) \
+ /* Callee-saved */ \
+ V(void*, x19) \
+ V(void*, x20) \
+ V(void*, x21) \
+ V(void*, x22) \
+ V(void*, x23) \
+ V(void*, x24) \
+ V(void*, x25) \
+ V(void*, x26) \
+ V(void*, x27) \
+ V(void*, x28) \
+ /* Special */ \
+ V(void*, fp) \
+ V(void*, lr) \
+ V(void*, sp)
</ins><span class="cx">
</span><ins>+#define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+ V(void*, pc) \
+ V(void*, nzcv) \
+ V(void*, fpsr) \
+
+// ARM64 always has 32 FPU registers 128-bits each. See http://llvm.org/devmtg/2012-11/Northover-AArch64.pdf
+// and Section 5.1.2 in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf.
+// However, we only use them for 64-bit doubles.
+#define FOR_EACH_CPU_FPREGISTER(V) \
+ /* Parameter/result registers */ \
+ V(double, q0) \
+ V(double, q1) \
+ V(double, q2) \
+ V(double, q3) \
+ V(double, q4) \
+ V(double, q5) \
+ V(double, q6) \
+ V(double, q7) \
+ /* Callee-saved (up to 64-bits only!) */ \
+ V(double, q8) \
+ V(double, q9) \
+ V(double, q10) \
+ V(double, q11) \
+ V(double, q12) \
+ V(double, q13) \
+ V(double, q14) \
+ V(double, q15) \
+ /* Temporary registers */ \
+ V(double, q16) \
+ V(double, q17) \
+ V(double, q18) \
+ V(double, q19) \
+ V(double, q20) \
+ V(double, q21) \
+ V(double, q22) \
+ V(double, q23) \
+ V(double, q24) \
+ V(double, q25) \
+ V(double, q26) \
+ V(double, q27) \
+ V(double, q28) \
+ V(double, q29) \
+ V(double, q30) \
+ V(double, q31)
+
+typedef enum {
+ #define DECLARE_REGISTER(_type, _regName) _regName,
+ FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+ #undef DECLARE_REGISTER
+
+ ip0 = x16,
+ ip1 = x17,
+ x29 = fp,
+ x30 = lr,
+ zr = 0x3f,
+} RegisterID;
+
+typedef enum {
+ #define DECLARE_REGISTER(_type, _regName) _regName,
+ FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+ #undef DECLARE_REGISTER
+} FPRegisterID;
+
+static constexpr bool isSp(RegisterID reg) { return reg == sp; }
+static constexpr bool isZr(RegisterID reg) { return reg == zr; }
+
+} // namespace ARM64Registers
+
</ins><span class="cx"> class ARM64Assembler {
</span><span class="cx"> public:
</span><span class="cx"> typedef ARM64Registers::RegisterID RegisterID;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -860,8 +860,9 @@
</span><span class="cx"> return #_regName;
</span><span class="cx"> FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
</span><span class="cx"> #undef DECLARE_REGISTER
</span><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><del>- RELEASE_ASSERT_NOT_REACHED();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static const char* fprName(FPRegisterID regID)
</span><span class="lines">@@ -872,8 +873,9 @@
</span><span class="cx"> return #_regName;
</span><span class="cx"> FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
</span><span class="cx"> #undef DECLARE_REGISTER
</span><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><del>- RELEASE_ASSERT_NOT_REACHED();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void* gpr(RegisterID regID)
</span><span class="lines">@@ -884,8 +886,9 @@
</span><span class="cx"> return _regName;
</span><span class="cx"> FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
</span><span class="cx"> #undef DECLARE_REGISTER
</span><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><del>- RELEASE_ASSERT_NOT_REACHED();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> double fpr(FPRegisterID regID)
</span><span class="lines">@@ -896,8 +899,9 @@
</span><span class="cx"> return _regName;
</span><span class="cx"> FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
</span><span class="cx"> #undef DECLARE_REGISTER
</span><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><del>- RELEASE_ASSERT_NOT_REACHED();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp (0 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp         (rev 0)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+/*
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(ASSEMBLER) && CPU(ARM64)
+#include "MacroAssemblerARM64.h"
+
+namespace JSC {
+
+#if ENABLE(MASM_PROBE)
+
+extern "C" void ctiMasmProbeTrampoline();
+
+using namespace ARM64Registers;
+
+static void arm64ProbeTrampoline(MacroAssemblerARM64::ProbeContext* context)
+{
+ void* origSP = context->cpu.sp;
+ void* origPC = context->cpu.pc;
+
+ context->probeFunction(context);
+
+ if (context->cpu.sp != origSP) {
+ dataLog("MacroAssembler probe ERROR: ARM64 does not support the probe changing the SP. The change will be ignored\n");
+ context->cpu.sp = origSP;
+ }
+ if (context->cpu.pc != origPC) {
+ dataLog("MacroAssembler probe ERROR: ARM64 does not support the probe changing the PC. The change will be ignored\n");
+ context->cpu.pc = origPC;
+ }
+}
+
+// For details on "What code is emitted for the probe?" and "What values are in
+// the saved registers?", see comment for MacroAssemblerX86Common::probe() in
+// MacroAssemblerX86Common.cpp.
+void MacroAssemblerARM64::probe(MacroAssemblerARM64::ProbeFunction function, void* arg1, void* arg2)
+{
+ sub64(TrustedImm32(8 * 8), sp);
+
+ store64(x27, Address(sp, 4 * 8));
+ store64(x28, Address(sp, 5 * 8));
+ store64(lr, Address(sp, 6 * 8));
+
+ add64(TrustedImm32(8 * 8), sp, x28);
+ store64(x28, Address(sp, 7 * 8)); // Save original sp value.
+
+ move(TrustedImmPtr(reinterpret_cast<void*>(function)), x28);
+ store64(x28, Address(sp));
+ move(TrustedImmPtr(arg1), x28);
+ store64(x28, Address(sp, 1 * 8));
+ move(TrustedImmPtr(arg2), x28);
+ store64(x28, Address(sp, 2 * 8));
+ move(TrustedImmPtr(reinterpret_cast<void*>(arm64ProbeTrampoline)), x28);
+ store64(x28, Address(sp, 3 * 8));
+
+ move(TrustedImmPtr(reinterpret_cast<void*>(ctiMasmProbeTrampoline)), x28);
+ m_assembler.blr(x28);
+
+ // ctiMasmProbeTrampoline should have restored every register except for
+ // lr and the sp.
+ load64(Address(sp, 6 * 8), lr);
+ add64(TrustedImm32(8 * 8), sp);
+}
+#endif // ENABLE(MASM_PROBE)
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && CPU(ARM64)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -2529,6 +2529,10 @@
</span><span class="cx"> ARM64Assembler::repatchPointer(call.dataLabelPtrAtOffset(REPATCH_OFFSET_CALL_TO_POINTER).dataLocation(), destination.executableAddress());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(MASM_PROBE)
+ void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
+#endif // ENABLE(MASM_PROBE)
+
</ins><span class="cx"> protected:
</span><span class="cx"> ALWAYS_INLINE Jump makeBranch(ARM64Assembler::Condition cond)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubs.cpp (191129 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubs.cpp        2015-10-15 19:52:34 UTC (rev 191129)
+++ trunk/Source/JavaScriptCore/jit/JITStubs.cpp        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -40,12 +40,12 @@
</span><span class="cx"> #include "JITStubsARM.h"
</span><span class="cx"> #elif CPU(ARM_THUMB2)
</span><span class="cx"> #include "JITStubsARMv7.h"
</span><ins>+#elif CPU(ARM64)
+#include "JITStubsARM64.h"
</ins><span class="cx"> #elif CPU(X86)
</span><span class="cx"> #include "JITStubsX86.h"
</span><span class="cx"> #elif CPU(X86_64)
</span><span class="cx"> #include "JITStubsX86_64.h"
</span><del>-#elif CPU(ARM64)
-// There isn't an ARM64 specific .h file
</del><span class="cx"> #elif CPU(MIPS)
</span><span class="cx"> // There isn't a MIPS specific .h file
</span><span class="cx"> #elif CPU(SH4)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubsARM64h"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/JITStubsARM64.h (0 => 191130)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubsARM64.h         (rev 0)
+++ trunk/Source/JavaScriptCore/jit/JITStubsARM64.h        2015-10-15 19:54:02 UTC (rev 191130)
</span><span class="lines">@@ -0,0 +1,457 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITStubsARM64_h
+#define JITStubsARM64_h
+
+#if !USE(JSVALUE64)
+#error "JITStubsARM64.h only implements USE(JSVALUE64)"
+#endif
+
+namespace JSC {
+
+#if COMPILER(GCC_OR_CLANG)
+
+#if ENABLE(MASM_PROBE)
+// The following are offsets for MacroAssembler::ProbeContext fields accessed
+// by the ctiMasmProbeTrampoline stub.
+
+#define PTR_SIZE 8
+#define PROBE_PROBE_FUNCTION_OFFSET (0 * PTR_SIZE)
+#define PROBE_ARG1_OFFSET (1 * PTR_SIZE)
+#define PROBE_ARG2_OFFSET (2 * PTR_SIZE)
+
+#define PROBE_FIRST_GPREG_OFFSET (3 * PTR_SIZE)
+
+#define GPREG_SIZE 8
+#define PROBE_CPU_X0_OFFSET (PROBE_FIRST_GPREG_OFFSET + (0 * GPREG_SIZE))
+#define PROBE_CPU_X1_OFFSET (PROBE_FIRST_GPREG_OFFSET + (1 * GPREG_SIZE))
+#define PROBE_CPU_X2_OFFSET (PROBE_FIRST_GPREG_OFFSET + (2 * GPREG_SIZE))
+#define PROBE_CPU_X3_OFFSET (PROBE_FIRST_GPREG_OFFSET + (3 * GPREG_SIZE))
+#define PROBE_CPU_X4_OFFSET (PROBE_FIRST_GPREG_OFFSET + (4 * GPREG_SIZE))
+#define PROBE_CPU_X5_OFFSET (PROBE_FIRST_GPREG_OFFSET + (5 * GPREG_SIZE))
+#define PROBE_CPU_X6_OFFSET (PROBE_FIRST_GPREG_OFFSET + (6 * GPREG_SIZE))
+#define PROBE_CPU_X7_OFFSET (PROBE_FIRST_GPREG_OFFSET + (7 * GPREG_SIZE))
+#define PROBE_CPU_X8_OFFSET (PROBE_FIRST_GPREG_OFFSET + (8 * GPREG_SIZE))
+#define PROBE_CPU_X9_OFFSET (PROBE_FIRST_GPREG_OFFSET + (9 * GPREG_SIZE))
+#define PROBE_CPU_X10_OFFSET (PROBE_FIRST_GPREG_OFFSET + (10 * GPREG_SIZE))
+#define PROBE_CPU_X11_OFFSET (PROBE_FIRST_GPREG_OFFSET + (11 * GPREG_SIZE))
+#define PROBE_CPU_X12_OFFSET (PROBE_FIRST_GPREG_OFFSET + (12 * GPREG_SIZE))
+#define PROBE_CPU_X13_OFFSET (PROBE_FIRST_GPREG_OFFSET + (13 * GPREG_SIZE))
+#define PROBE_CPU_X14_OFFSET (PROBE_FIRST_GPREG_OFFSET + (14 * GPREG_SIZE))
+#define PROBE_CPU_X15_OFFSET (PROBE_FIRST_GPREG_OFFSET + (15 * GPREG_SIZE))
+#define PROBE_CPU_X16_OFFSET (PROBE_FIRST_GPREG_OFFSET + (16 * GPREG_SIZE))
+#define PROBE_CPU_X17_OFFSET (PROBE_FIRST_GPREG_OFFSET + (17 * GPREG_SIZE))
+#define PROBE_CPU_X18_OFFSET (PROBE_FIRST_GPREG_OFFSET + (18 * GPREG_SIZE))
+#define PROBE_CPU_X19_OFFSET (PROBE_FIRST_GPREG_OFFSET + (19 * GPREG_SIZE))
+#define PROBE_CPU_X20_OFFSET (PROBE_FIRST_GPREG_OFFSET + (20 * GPREG_SIZE))
+#define PROBE_CPU_X21_OFFSET (PROBE_FIRST_GPREG_OFFSET + (21 * GPREG_SIZE))
+#define PROBE_CPU_X22_OFFSET (PROBE_FIRST_GPREG_OFFSET + (22 * GPREG_SIZE))
+#define PROBE_CPU_X23_OFFSET (PROBE_FIRST_GPREG_OFFSET + (23 * GPREG_SIZE))
+#define PROBE_CPU_X24_OFFSET (PROBE_FIRST_GPREG_OFFSET + (24 * GPREG_SIZE))
+#define PROBE_CPU_X25_OFFSET (PROBE_FIRST_GPREG_OFFSET + (25 * GPREG_SIZE))
+#define PROBE_CPU_X26_OFFSET (PROBE_FIRST_GPREG_OFFSET + (26 * GPREG_SIZE))
+#define PROBE_CPU_X27_OFFSET (PROBE_FIRST_GPREG_OFFSET + (27 * GPREG_SIZE))
+#define PROBE_CPU_X28_OFFSET (PROBE_FIRST_GPREG_OFFSET + (28 * GPREG_SIZE))
+#define PROBE_CPU_FP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (29 * GPREG_SIZE))
+#define PROBE_CPU_LR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (30 * GPREG_SIZE))
+#define PROBE_CPU_SP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (31 * GPREG_SIZE))
+
+#define PROBE_CPU_PC_OFFSET (PROBE_FIRST_GPREG_OFFSET + (32 * GPREG_SIZE))
+#define PROBE_CPU_NZCV_OFFSET (PROBE_FIRST_GPREG_OFFSET + (33 * GPREG_SIZE))
+#define PROBE_CPU_FPSR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (34 * GPREG_SIZE))
+
+#define PROBE_FIRST_FPREG_OFFSET (PROBE_FIRST_GPREG_OFFSET + (35 * GPREG_SIZE))
+
+#define FPREG_SIZE 8
+#define PROBE_CPU_Q0_OFFSET (PROBE_FIRST_FPREG_OFFSET + (0 * FPREG_SIZE))
+#define PROBE_CPU_Q1_OFFSET (PROBE_FIRST_FPREG_OFFSET + (1 * FPREG_SIZE))
+#define PROBE_CPU_Q2_OFFSET (PROBE_FIRST_FPREG_OFFSET + (2 * FPREG_SIZE))
+#define PROBE_CPU_Q3_OFFSET (PROBE_FIRST_FPREG_OFFSET + (3 * FPREG_SIZE))
+#define PROBE_CPU_Q4_OFFSET (PROBE_FIRST_FPREG_OFFSET + (4 * FPREG_SIZE))
+#define PROBE_CPU_Q5_OFFSET (PROBE_FIRST_FPREG_OFFSET + (5 * FPREG_SIZE))
+#define PROBE_CPU_Q6_OFFSET (PROBE_FIRST_FPREG_OFFSET + (6 * FPREG_SIZE))
+#define PROBE_CPU_Q7_OFFSET (PROBE_FIRST_FPREG_OFFSET + (7 * FPREG_SIZE))
+#define PROBE_CPU_Q8_OFFSET (PROBE_FIRST_FPREG_OFFSET + (8 * FPREG_SIZE))
+#define PROBE_CPU_Q9_OFFSET (PROBE_FIRST_FPREG_OFFSET + (9 * FPREG_SIZE))
+#define PROBE_CPU_Q10_OFFSET (PROBE_FIRST_FPREG_OFFSET + (10 * FPREG_SIZE))
+#define PROBE_CPU_Q11_OFFSET (PROBE_FIRST_FPREG_OFFSET + (11 * FPREG_SIZE))
+#define PROBE_CPU_Q12_OFFSET (PROBE_FIRST_FPREG_OFFSET + (12 * FPREG_SIZE))
+#define PROBE_CPU_Q13_OFFSET (PROBE_FIRST_FPREG_OFFSET + (13 * FPREG_SIZE))
+#define PROBE_CPU_Q14_OFFSET (PROBE_FIRST_FPREG_OFFSET + (14 * FPREG_SIZE))
+#define PROBE_CPU_Q15_OFFSET (PROBE_FIRST_FPREG_OFFSET + (15 * FPREG_SIZE))
+#define PROBE_CPU_Q16_OFFSET (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE))
+#define PROBE_CPU_Q17_OFFSET (PROBE_FIRST_FPREG_OFFSET + (17 * FPREG_SIZE))
+#define PROBE_CPU_Q18_OFFSET (PROBE_FIRST_FPREG_OFFSET + (18 * FPREG_SIZE))
+#define PROBE_CPU_Q19_OFFSET (PROBE_FIRST_FPREG_OFFSET + (19 * FPREG_SIZE))
+#define PROBE_CPU_Q20_OFFSET (PROBE_FIRST_FPREG_OFFSET + (20 * FPREG_SIZE))
+#define PROBE_CPU_Q21_OFFSET (PROBE_FIRST_FPREG_OFFSET + (21 * FPREG_SIZE))
+#define PROBE_CPU_Q22_OFFSET (PROBE_FIRST_FPREG_OFFSET + (22 * FPREG_SIZE))
+#define PROBE_CPU_Q23_OFFSET (PROBE_FIRST_FPREG_OFFSET + (23 * FPREG_SIZE))
+#define PROBE_CPU_Q24_OFFSET (PROBE_FIRST_FPREG_OFFSET + (24 * FPREG_SIZE))
+#define PROBE_CPU_Q25_OFFSET (PROBE_FIRST_FPREG_OFFSET + (25 * FPREG_SIZE))
+#define PROBE_CPU_Q26_OFFSET (PROBE_FIRST_FPREG_OFFSET + (26 * FPREG_SIZE))
+#define PROBE_CPU_Q27_OFFSET (PROBE_FIRST_FPREG_OFFSET + (27 * FPREG_SIZE))
+#define PROBE_CPU_Q28_OFFSET (PROBE_FIRST_FPREG_OFFSET + (28 * FPREG_SIZE))
+#define PROBE_CPU_Q29_OFFSET (PROBE_FIRST_FPREG_OFFSET + (29 * FPREG_SIZE))
+#define PROBE_CPU_Q30_OFFSET (PROBE_FIRST_FPREG_OFFSET + (30 * FPREG_SIZE))
+#define PROBE_CPU_Q31_OFFSET (PROBE_FIRST_FPREG_OFFSET + (31 * FPREG_SIZE))
+#define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (32 * FPREG_SIZE))
+#define SAVED_CALLER_SP PROBE_SIZE
+#define PROBE_SIZE_PLUS_SAVED_CALLER_SP (SAVED_CALLER_SP + PTR_SIZE)
+
+// These ASSERTs remind you that if you change the layout of ProbeContext,
+// you need to change ctiMasmProbeTrampoline offsets above to match.
+#define PROBE_OFFSETOF(x) offsetof(struct MacroAssembler::ProbeContext, x)
+COMPILE_ASSERT(PROBE_OFFSETOF(probeFunction) == PROBE_PROBE_FUNCTION_OFFSET, ProbeContext_probeFunction_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(arg1) == PROBE_ARG1_OFFSET, ProbeContext_arg1_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(arg2) == PROBE_ARG2_OFFSET, ProbeContext_arg2_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x0) == PROBE_CPU_X0_OFFSET, ProbeContext_cpu_x0_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x1) == PROBE_CPU_X1_OFFSET, ProbeContext_cpu_x1_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x2) == PROBE_CPU_X2_OFFSET, ProbeContext_cpu_x2_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x3) == PROBE_CPU_X3_OFFSET, ProbeContext_cpu_x3_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x4) == PROBE_CPU_X4_OFFSET, ProbeContext_cpu_x4_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x5) == PROBE_CPU_X5_OFFSET, ProbeContext_cpu_x5_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x6) == PROBE_CPU_X6_OFFSET, ProbeContext_cpu_x6_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x7) == PROBE_CPU_X7_OFFSET, ProbeContext_cpu_x7_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x8) == PROBE_CPU_X8_OFFSET, ProbeContext_cpu_x8_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x9) == PROBE_CPU_X9_OFFSET, ProbeContext_cpu_x9_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x10) == PROBE_CPU_X10_OFFSET, ProbeContext_cpu_x10_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x11) == PROBE_CPU_X11_OFFSET, ProbeContext_cpu_x11_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x12) == PROBE_CPU_X12_OFFSET, ProbeContext_cpu_x12_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x13) == PROBE_CPU_X13_OFFSET, ProbeContext_cpu_x13_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x14) == PROBE_CPU_X14_OFFSET, ProbeContext_cpu_x14_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x15) == PROBE_CPU_X15_OFFSET, ProbeContext_cpu_x15_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x16) == PROBE_CPU_X16_OFFSET, ProbeContext_cpu_x16_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x17) == PROBE_CPU_X17_OFFSET, ProbeContext_cpu_x17_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x18) == PROBE_CPU_X18_OFFSET, ProbeContext_cpu_x18_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x19) == PROBE_CPU_X19_OFFSET, ProbeContext_cpu_x19_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x20) == PROBE_CPU_X20_OFFSET, ProbeContext_cpu_x20_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x21) == PROBE_CPU_X21_OFFSET, ProbeContext_cpu_x21_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x22) == PROBE_CPU_X22_OFFSET, ProbeContext_cpu_x22_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x23) == PROBE_CPU_X23_OFFSET, ProbeContext_cpu_x23_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x24) == PROBE_CPU_X24_OFFSET, ProbeContext_cpu_x24_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x25) == PROBE_CPU_X25_OFFSET, ProbeContext_cpu_x25_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x26) == PROBE_CPU_X26_OFFSET, ProbeContext_cpu_x26_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x27) == PROBE_CPU_X27_OFFSET, ProbeContext_cpu_x27_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.x28) == PROBE_CPU_X28_OFFSET, ProbeContext_cpu_x28_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fp) == PROBE_CPU_FP_OFFSET, ProbeContext_cpu_fp_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.lr) == PROBE_CPU_LR_OFFSET, ProbeContext_cpu_lr_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.sp) == PROBE_CPU_SP_OFFSET, ProbeContext_cpu_sp_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.pc) == PROBE_CPU_PC_OFFSET, ProbeContext_cpu_pc_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.nzcv) == PROBE_CPU_NZCV_OFFSET, ProbeContext_cpu_nzcv_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fpsr) == PROBE_CPU_FPSR_OFFSET, ProbeContext_cpu_fpsr_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q0) == PROBE_CPU_Q0_OFFSET, ProbeContext_cpu_q0_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q1) == PROBE_CPU_Q1_OFFSET, ProbeContext_cpu_q1_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q2) == PROBE_CPU_Q2_OFFSET, ProbeContext_cpu_q2_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q3) == PROBE_CPU_Q3_OFFSET, ProbeContext_cpu_q3_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q4) == PROBE_CPU_Q4_OFFSET, ProbeContext_cpu_q4_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q5) == PROBE_CPU_Q5_OFFSET, ProbeContext_cpu_q5_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q6) == PROBE_CPU_Q6_OFFSET, ProbeContext_cpu_q6_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q7) == PROBE_CPU_Q7_OFFSET, ProbeContext_cpu_q7_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q8) == PROBE_CPU_Q8_OFFSET, ProbeContext_cpu_q8_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q9) == PROBE_CPU_Q9_OFFSET, ProbeContext_cpu_q9_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q10) == PROBE_CPU_Q10_OFFSET, ProbeContext_cpu_q10_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q11) == PROBE_CPU_Q11_OFFSET, ProbeContext_cpu_q11_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q12) == PROBE_CPU_Q12_OFFSET, ProbeContext_cpu_q12_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q13) == PROBE_CPU_Q13_OFFSET, ProbeContext_cpu_q13_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q14) == PROBE_CPU_Q14_OFFSET, ProbeContext_cpu_q14_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q15) == PROBE_CPU_Q15_OFFSET, ProbeContext_cpu_q15_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q16) == PROBE_CPU_Q16_OFFSET, ProbeContext_cpu_q16_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q17) == PROBE_CPU_Q17_OFFSET, ProbeContext_cpu_q17_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q18) == PROBE_CPU_Q18_OFFSET, ProbeContext_cpu_q18_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q19) == PROBE_CPU_Q19_OFFSET, ProbeContext_cpu_q19_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q20) == PROBE_CPU_Q20_OFFSET, ProbeContext_cpu_q20_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q21) == PROBE_CPU_Q21_OFFSET, ProbeContext_cpu_q21_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q22) == PROBE_CPU_Q22_OFFSET, ProbeContext_cpu_q22_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q23) == PROBE_CPU_Q23_OFFSET, ProbeContext_cpu_q23_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q24) == PROBE_CPU_Q24_OFFSET, ProbeContext_cpu_q24_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q25) == PROBE_CPU_Q25_OFFSET, ProbeContext_cpu_q25_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q26) == PROBE_CPU_Q26_OFFSET, ProbeContext_cpu_q26_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q27) == PROBE_CPU_Q27_OFFSET, ProbeContext_cpu_q27_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q28) == PROBE_CPU_Q28_OFFSET, ProbeContext_cpu_q28_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q29) == PROBE_CPU_Q29_OFFSET, ProbeContext_cpu_q29_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q30) == PROBE_CPU_Q30_OFFSET, ProbeContext_cpu_q30_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.q31) == PROBE_CPU_Q31_OFFSET, ProbeContext_cpu_q31_offset_matches_ctiMasmProbeTrampoline);
+
+COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
+
+#undef PROBE_OFFSETOF
+
+asm (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
+HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
+SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
+
+ // MacroAssembler::probe() has already generated code to store some values.
+ // The top of stack (the caller save buffer) now looks like this:
+ // sp[0 * ptrSize]: probeFunction
+ // sp[1 * ptrSize]: arg1
+ // sp[2 * ptrSize]: arg2
+ // sp[3 * ptrSize]: address of arm64ProbeTrampoline()
+ // sp[4 * ptrSize]: saved x27
+ // sp[5 * ptrSize]: saved x28
+ // sp[6 * ptrSize]: saved lr
+ // sp[7 * ptrSize]: saved sp
+
+ "mov x27, sp" "\n"
+ "mov x28, sp" "\n"
+
+ "sub x28, x28, #" STRINGIZE_VALUE_OF(PROBE_SIZE_PLUS_SAVED_CALLER_SP) "\n"
+
+ // The ARM EABI specifies that the stack needs to be 16 byte aligned.
+ "bic x28, x28, #0xf" "\n"
+ "mov sp, x28" "\n"
+
+ "str x27, [sp, #" STRINGIZE_VALUE_OF(SAVED_CALLER_SP) "]" "\n"
+
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X0_OFFSET) "]" "\n"
+ "str x1, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X1_OFFSET) "]" "\n"
+ "str x2, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X2_OFFSET) "]" "\n"
+ "str x3, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X3_OFFSET) "]" "\n"
+ "str x4, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X4_OFFSET) "]" "\n"
+ "str x5, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X5_OFFSET) "]" "\n"
+ "str x6, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X6_OFFSET) "]" "\n"
+ "str x7, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X7_OFFSET) "]" "\n"
+ "str x8, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X8_OFFSET) "]" "\n"
+ "str x9, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X9_OFFSET) "]" "\n"
+ "str x10, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X10_OFFSET) "]" "\n"
+ "str x11, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X11_OFFSET) "]" "\n"
+ "str x12, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X12_OFFSET) "]" "\n"
+ "str x13, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X13_OFFSET) "]" "\n"
+ "str x14, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X14_OFFSET) "]" "\n"
+ "str x15, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X15_OFFSET) "]" "\n"
+ "str x16, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X16_OFFSET) "]" "\n"
+ "str x17, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X17_OFFSET) "]" "\n"
+ "str x18, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X18_OFFSET) "]" "\n"
+ "str x19, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X19_OFFSET) "]" "\n"
+ "str x20, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X20_OFFSET) "]" "\n"
+ "str x21, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X21_OFFSET) "]" "\n"
+ "str x22, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X22_OFFSET) "]" "\n"
+ "str x23, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X23_OFFSET) "]" "\n"
+ "str x24, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X24_OFFSET) "]" "\n"
+ "str x25, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X25_OFFSET) "]" "\n"
+ "str x26, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X26_OFFSET) "]" "\n"
+
+ "ldr x0, [x27, #4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X27_OFFSET) "]" "\n"
+ "ldr x0, [x27, #5 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X28_OFFSET) "]" "\n"
+
+ "str fp, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FP_OFFSET) "]" "\n"
+
+ "ldr x0, [x27, #6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n"
+ "ldr x0, [x27, #7 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n"
+
+ "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n"
+
+ "mrs x0, nzcv" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_NZCV_OFFSET) "]" "\n"
+ "mrs x0, fpsr" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSR_OFFSET) "]" "\n"
+
+ "ldr x0, [x27, #0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "]" "\n"
+ "ldr x0, [x27, #1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG1_OFFSET) "]" "\n"
+ "ldr x0, [x27, #2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "str x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG2_OFFSET) "]" "\n"
+
+ "str d0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q0_OFFSET) "]" "\n"
+ "str d1, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q1_OFFSET) "]" "\n"
+ "str d2, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q2_OFFSET) "]" "\n"
+ "str d3, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q3_OFFSET) "]" "\n"
+ "str d4, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q4_OFFSET) "]" "\n"
+ "str d5, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q5_OFFSET) "]" "\n"
+ "str d6, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q6_OFFSET) "]" "\n"
+ "str d7, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q7_OFFSET) "]" "\n"
+ "str d8, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q8_OFFSET) "]" "\n"
+ "str d9, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q9_OFFSET) "]" "\n"
+ "str d10, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q10_OFFSET) "]" "\n"
+ "str d11, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q11_OFFSET) "]" "\n"
+ "str d12, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q12_OFFSET) "]" "\n"
+ "str d13, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q13_OFFSET) "]" "\n"
+ "str d14, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q14_OFFSET) "]" "\n"
+ "str d15, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q15_OFFSET) "]" "\n"
+ "str d16, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q16_OFFSET) "]" "\n"
+ "str d17, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q17_OFFSET) "]" "\n"
+ "str d18, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q18_OFFSET) "]" "\n"
+ "str d19, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q19_OFFSET) "]" "\n"
+ "str d20, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q20_OFFSET) "]" "\n"
+ "str d21, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q21_OFFSET) "]" "\n"
+ "str d22, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q22_OFFSET) "]" "\n"
+ "str d23, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q23_OFFSET) "]" "\n"
+ "str d24, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q24_OFFSET) "]" "\n"
+ "str d25, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q25_OFFSET) "]" "\n"
+ "str d26, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q26_OFFSET) "]" "\n"
+ "str d27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q27_OFFSET) "]" "\n"
+ "str d28, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q28_OFFSET) "]" "\n"
+ "str d29, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q29_OFFSET) "]" "\n"
+ "str d30, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q30_OFFSET) "]" "\n"
+ "str d31, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q31_OFFSET) "]" "\n"
+
+ "mov x28, sp" "\n" // Save the ProbeContext*.
+
+ "mov x0, sp" "\n" // the ProbeContext* arg.
+ "ldr x27, [x27, #3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+ "blr x27" "\n"
+
+ "mov sp, x28" "\n"
+
+ // To enable probes to modify register state, we copy all registers
+ // out of the ProbeContext before returning. That is except for x18, pc and sp.
+
+ // x18 is "reserved for the platform. Conforming software should not make use of it."
+ // Hence, the JITs would not be using it, and the probe should also not be modifying it.
+ // See https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html.
+
+ // We can't modify the pc, because the only way to set its value on ARM64 is via
+ // an indirect branch or a ret, which means we'll need a free register to do so.
+ // The probe mechanism is required to not perturb any registers that the caller
+ // may use. Hence, we don't have this free register available.
+
+ // In order to return to the caller, we need to ret via lr. The probe mechanism will
+ // restore lr's value after returning to the caller by loading the restore value
+ // from the caller save buffer. The caller expects to access the caller save buffer via
+ // sp. Hence, we cannot allow sp to be modified by the probe.
+
+ "ldr d0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q0_OFFSET) "]" "\n"
+ "ldr d1, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q1_OFFSET) "]" "\n"
+ "ldr d2, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q2_OFFSET) "]" "\n"
+ "ldr d3, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q3_OFFSET) "]" "\n"
+ "ldr d4, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q4_OFFSET) "]" "\n"
+ "ldr d5, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q5_OFFSET) "]" "\n"
+ "ldr d6, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q6_OFFSET) "]" "\n"
+ "ldr d7, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q7_OFFSET) "]" "\n"
+ "ldr d8, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q8_OFFSET) "]" "\n"
+ "ldr d9, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q9_OFFSET) "]" "\n"
+ "ldr d10, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q10_OFFSET) "]" "\n"
+ "ldr d11, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q11_OFFSET) "]" "\n"
+ "ldr d12, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q12_OFFSET) "]" "\n"
+ "ldr d13, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q13_OFFSET) "]" "\n"
+ "ldr d14, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q14_OFFSET) "]" "\n"
+ "ldr d15, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q15_OFFSET) "]" "\n"
+ "ldr d16, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q16_OFFSET) "]" "\n"
+ "ldr d17, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q17_OFFSET) "]" "\n"
+ "ldr d18, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q18_OFFSET) "]" "\n"
+ "ldr d19, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q19_OFFSET) "]" "\n"
+ "ldr d20, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q20_OFFSET) "]" "\n"
+ "ldr d21, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q21_OFFSET) "]" "\n"
+ "ldr d22, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q22_OFFSET) "]" "\n"
+ "ldr d23, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q23_OFFSET) "]" "\n"
+ "ldr d24, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q24_OFFSET) "]" "\n"
+ "ldr d25, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q25_OFFSET) "]" "\n"
+ "ldr d26, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q26_OFFSET) "]" "\n"
+ "ldr d27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q27_OFFSET) "]" "\n"
+ "ldr d28, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q28_OFFSET) "]" "\n"
+ "ldr d29, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q29_OFFSET) "]" "\n"
+ "ldr d30, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q30_OFFSET) "]" "\n"
+ "ldr d31, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_Q31_OFFSET) "]" "\n"
+
+ "ldr x0, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X0_OFFSET) "]" "\n"
+ "ldr x1, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X1_OFFSET) "]" "\n"
+ "ldr x2, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X2_OFFSET) "]" "\n"
+ "ldr x3, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X3_OFFSET) "]" "\n"
+ "ldr x4, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X4_OFFSET) "]" "\n"
+ "ldr x5, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X5_OFFSET) "]" "\n"
+ "ldr x6, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X6_OFFSET) "]" "\n"
+ "ldr x7, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X7_OFFSET) "]" "\n"
+ "ldr x8, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X8_OFFSET) "]" "\n"
+ "ldr x9, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X9_OFFSET) "]" "\n"
+ "ldr x10, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X10_OFFSET) "]" "\n"
+ "ldr x11, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X11_OFFSET) "]" "\n"
+ "ldr x12, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X12_OFFSET) "]" "\n"
+ "ldr x13, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X13_OFFSET) "]" "\n"
+ "ldr x14, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X14_OFFSET) "]" "\n"
+ "ldr x15, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X15_OFFSET) "]" "\n"
+ "ldr x16, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X16_OFFSET) "]" "\n"
+ "ldr x17, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X17_OFFSET) "]" "\n"
+ // x18 should not be modified by the probe. See comment above for details.
+ "ldr x19, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X19_OFFSET) "]" "\n"
+ "ldr x20, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X20_OFFSET) "]" "\n"
+ "ldr x21, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X21_OFFSET) "]" "\n"
+ "ldr x22, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X22_OFFSET) "]" "\n"
+ "ldr x23, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X23_OFFSET) "]" "\n"
+ "ldr x24, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X24_OFFSET) "]" "\n"
+ "ldr x25, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X25_OFFSET) "]" "\n"
+ "ldr x26, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X26_OFFSET) "]" "\n"
+
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSR_OFFSET) "]" "\n"
+ "msr fpsr, x27" "\n"
+
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_NZCV_OFFSET) "]" "\n"
+ "msr nzcv, x27" "\n"
+ "ldr fp, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FP_OFFSET) "]" "\n"
+
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X27_OFFSET) "]" "\n"
+ "ldr x28, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X28_OFFSET) "]" "\n"
+
+ // There are 4 more registers left to restore: x27, x28, lr, sp, and pc.
+ // The JIT code's lr and sp will be restored by the caller.
+
+ // Restore pc by loading it into lr. The ret below will put in the pc.
+ "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n"
+
+ // We need x27 as a scratch register to help with popping the ProbeContext.
+ // Hence, before we pop the ProbeContext, we need to copy the restore value
+ // for x27 from the ProbeContext to the caller save buffer.
+ "ldr x28, [sp, #" STRINGIZE_VALUE_OF(SAVED_CALLER_SP) "]" "\n"
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X27_OFFSET) "]" "\n"
+ "str x27, [x28, #4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+
+ // Since lr is also restored by the caller, we need to copy its restore
+ // value to the caller save buffer too.
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n"
+ "str x27, [x28, #6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+
+ // We're now done with x28, and can restore its value.
+ "ldr x28, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_X28_OFFSET) "]" "\n"
+
+ // We're now done with the ProbeContext, and can pop it to restore sp so that
+ // it points to the caller save buffer.
+ "ldr x27, [sp, #" STRINGIZE_VALUE_OF(SAVED_CALLER_SP) "]" "\n"
+ "mov sp, x27" "\n"
+
+ // We're now done with x27, and can restore it.
+ "ldr x27, [sp, #4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n"
+
+ "ret" "\n"
+);
+#endif // ENABLE(MASM_PROBE)
+
+#endif // COMPILER(GCC_OR_CLANG)
+
+} // namespace JSC
+
+#endif // JITStubsARM64_h
</ins></span></pre>
</div>
</div>
</body>
</html>