{"id":112747,"date":"2026-10-01T07:00:57","date_gmt":"2026-10-01T14:00:57","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112747"},"modified":"2026-10-01T22:10:37","modified_gmt":"2026-10-02T05:10:37","slug":"windows-on-itanium-also-provided-for-hot-patching-in-an-even-simpler-way","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20261001-57\/?p=112747\/","title":{"rendered":"Windows on Itanium also provided for hot-patching, in an even simpler way"},"content":{"rendered":"<p>Last time, we looked at <a title=\"Windows on AArch64 also provides for hot-patching, but it's much simpler than on x86\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20260930-00\/?p=112744\"> Windows hot-patching on 64-bit ARM<\/a>. But what about Itanium?<\/p>\n<p>Oh, you remembered Itanium!<\/p>\n<p>Itanium also had fixed-sized instructions, or more accurately, fixed-sized bundles, where each bundle encodes three instructions. Fixed-size bundles mean that, like AArch64, there is no hot-patching restriction on the first instruction of a function.<\/p>\n<p>In fact, there was no spare space for hot-patching at all.<\/p>\n<p>Because none was needed.<\/p>\n<p>During hot-patching, the first bundle of the instruction could be overwritten with<\/p>\n<pre>        nop\r\n        brl.cond.sptk target64\r\n<\/pre>\n<p>The second instruction <code>brl<\/code> is a &#8220;long branch&#8221; that accepts a 64-bit target.\u00b9 This is a &#8220;double-wide&#8221; instruction that takes up two slots in the bundle, which is why we see a bundle of only two instructions.<\/p>\n<p>Based on my experience with AArch64, I thought at first that the instruction sequence would be more like<\/p>\n<pre>    movl r8 = target64   \/* double-wide 64-bit load instruction *\/\r\n    br.cond.sptk r8\r\n<\/pre>\n<p>But then I realized that this doesn&#8217;t work because you cannot perform an indirect jump through a general-purpose register. You have to move it to a branch register first. and that would take us to four instructions (since the <code>movl<\/code> occupies two slots), which exceeds the capacity of a bundle.<\/p>\n<p><b>Bonus chatter<\/b>: If you study some old Itanium binaries like I did, you will find that many functions are preceded by an apparent spare bundle:<\/p>\n<pre>    break.m 0\r\n    break.i 0\r\n    break.i 0\r\n<\/pre>\n<p>This is a bundle full of breakpoint instructions, and you might be tricked (like me) into thinking that they are there for hot-patching. But then you find that some other functions don&#8217;t have this spare bundle, and after closer study, you realize that this spare bundle is not for hot patching. It&#8217;s padding to bring the start of every function to a 32-byte boundary.<\/p>\n<p>\u00b9 Formally, it&#8217;s a conditional long branch instruction predicated on <code>p0<\/code>, and statically predicted to be taken. The <code>p0<\/code> register is hard-wired to <i>true<\/i>, so the assembler conveniently simplifies the disassembly and omits the <code>p0<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Once again, the benefit of fixed-length instructions.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-112747","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Once again, the benefit of fixed-length instructions.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112747","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=112747"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112747\/revisions"}],"predecessor-version":[{"id":112748,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112747\/revisions\/112748"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=112747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112747"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}