{"id":106948,"date":"2022-08-05T07:00:00","date_gmt":"2022-08-05T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106948"},"modified":"2022-08-05T06:52:01","modified_gmt":"2022-08-05T13:52:01","slug":"20220805-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20220805-00\/?p=106948","title":{"rendered":"The AArch64 processor (aka arm64), part 9: Sign and zero extension"},"content":{"rendered":"<p>AArch64 does not have dedicated sign and zero-extension instructions because they can be synthesized as pseudo-instructions from the bitfield extraction instructions.<\/p>\n<pre>    ; unsigned extend byte\r\n    ; Rd = (uint8_t)Rn\r\n    uxtb    Rd\/zr, Rn\/zr        ; ubfx Rd, Rn, #0, #8\r\n\r\n    ; unsigned extend halfword\r\n    ; Rd = (uint16_t)Rn\r\n    uxth    Rd\/zr, Rn\/zr        ; ubfx Rd, Rn, #0, #16\r\n\r\n    ; signed extend byte\r\n    ; Rd = (int8_t)Rn\r\n    sxtb    Rd\/zr, Rn\/zr        ; sbfx Rd, Rn, #0, #8\r\n\r\n    ; signed extend halfword\r\n    ; Rd = (int16_t)Rn\r\n    sxth    Rd\/zr, Rn\/zr        ; sbfx Rd, Rn, #0, #16\r\n\r\n    ; unsigned extend word\r\n    mov     Wd, Wn\r\n\r\n    ; signed extend word\r\n    sxtw    Xd\/zr, Xn\/zr        ; sbfx Xd, Xn, #0, #32\r\n<\/pre>\n<p>The odd man out here is the lack of an unsigned extend word pseudo-instruction, but a <code>MOV<\/code> works just as well, because the rule for 32-bit destinations is that they are zero-extended to a 64-bit value. So just moving a 32-bit register secretly zero-extends it. In practice, you can usually get the zero-extension for free by using a 32-bit register as the destination for the original calculation.<\/p>\n<p>You can avoid having using these instructions if you can merge it into a subsequent extended register operation:<\/p>\n<pre>    ; as two instructions, using r3 as scratch register\r\n    uxtb    r3, r2              ; r3 = (uint8_t)r2\r\n    add     r0, r1, r3          ; r0 = r1 + r3\r\n\r\n    ; merged into one instruction, avoids scratch register\r\n    add     r0, r1, r2, uxtb    ; r0 = r1 + (uint8_t)r2\r\n<\/pre>\n<p>For extending a word to a doubleword, you can synthesize that easily enough:<\/p>\n<pre>    ; unsigned extend word in Xd to doubleword in Xd\/X(d+1)\r\n    mov     X(d+1), #0\r\n\r\n    ; signed extend word in Xd to doubleword in Xd\/X(d+1)\r\n    asr     X(d+1), Xd, #63 ; copy sign bits to all bits\r\n<\/pre>\n<p>Next time, we&#8217;ll look at ways of loading constants.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nothing new here, but old things being used in clever ways.<\/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":[2],"class_list":["post-106948","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Nothing new here, but old things being used in clever ways.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106948","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=106948"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106948\/revisions"}],"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=106948"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106948"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}