{"id":96785,"date":"2017-08-09T07:00:00","date_gmt":"2017-08-09T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96785"},"modified":"2019-03-13T01:15:03","modified_gmt":"2019-03-13T08:15:03","slug":"20170809-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170809-00\/?p=96785","title":{"rendered":"The Alpha AXP, part 3: Integer constants"},"content":{"rendered":"<p>The Alpha AXP does not have a &#8220;load immediate 32-bit integer&#8221; instruction. If you need to load an immediate 32-bit integer, you need to use some tricks. <\/p>\n<p>We saw last time that <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20170808-00\/?p=96775\">loading 8-bit constants can be done by using the <code>ADD<\/code> and <code>SUB<\/code> instructions<\/a>. But there are also instructions that can be repurposed to generate signed 16-bit constants. <\/p>\n<p>Effective address instructions are basically arithmetic operations disguised as memory operations. (Yes, I know we haven&#8217;t learned about memory operations yet.) <\/p>\n<pre>\n    LDA     Ra, disp16(Rb)  ; Ra = Rb + (int16_t)disp16\n    LDAH    Ra, disp16(Rb)  ; Ra = Rb + (int16_t)disp16 * 65536\n<\/pre>\n<p>The first instruction applies a signed 16-bit displacement to a value in a register and puts the result in the <var>Ra<\/var> register. <\/p>\n<p>The second one is a little trickier. It takes the signed 16-bit displacement and shifts it left 16 positions before adding it to the <var>Rb<\/var> register. <\/p>\n<p>Both of these operations operate on the full 64-bit register, so they can produce non-canonical results. <\/p>\n<p>The basic idea behind loading a 32-bit constant (in canonical form) is as follows: <\/p>\n<ol>\n<li>Use the <code>LDAH<\/code>      relative to the <var>zero<\/var> register     to load the high-order 48 bits of the     32-bit constant. \n<li>Use the <code>LDA<\/code> instruction     relative to the destination register     of the previous instruction     to load the low-order 16 bits.<\/li>\n<\/li>\n<\/ol>\n<p>However, the fact that the 16-bit values are sign-extended makes things a bit more complicated. <\/p>\n<p>Let&#8217;s say that the 32-bit constant we want to load into the <var>t0<\/var> register is <code>0xXXXXYYYY<\/code>. <\/p>\n<p>Let <code>xxxx<\/code> be the result you get when you treat <code>XXXX<\/code> as a signed 16-bit value. Similarly, <code>yyyy<\/code> and <code>YYYY<\/code>. <\/p>\n<p>Let <code>S<\/code> be the sign bit of <code>XXXX<\/code>. The canonical form of the constant we want to load is <code>0xSSSSSSSS`XXXXYYYY<\/code>. <\/p>\n<p>If <code>yyyy<\/code> is nonnegative, then we can just load up the two halves of our constant and they won&#8217;t interact with each other. <\/p>\n<pre>\n    LDAH    t0, XXXX(zero)      ; t0 = 0xSSSSSSSS`XXXX0000\n    LDA     t0, YYYY(t0)        ; t0 = 0xSSSSSSSS`XXXXYYYY\n<\/pre>\n<p>(Throughout, I will leave out the obvious simplifications if <code>XXXX<\/code> or <code>YYYY<\/code> is zero.) <\/p>\n<p>If <code>yyyy<\/code> is negative, then the <code>LDA<\/code> is going to undershoot by <code>0x10000<\/code>, so we compensate by adding one more to <code>xxxx<\/code>. <\/p>\n<p><pre>\n    LDAH    t0, xxxx+1(zero)    ; t0 = 0xSSSSSSSS`XXXX0000 + 0x10000\n    LDA     t0, yyyy(t0)        ; t0 = 0xSSSSSSSS`XXXXYYYY\n<\/pre>\n<p>Aha, but this trick doesn&#8217;t work if <code>xxxx<\/code> is exactly <code>0x7FFF<\/code>, because <code>0x7FFF<\/code> + 1 = <code>0x8000<\/code>, which has the wrong sign bit. In that case, we need a final adjustment step to put the result into canonical form. <\/p>\n<pre>\n    LDAH    t0, -32768(zero)    ; t0 = 0xFFFFFFFF`80000000\n    LDA     t0, yyyy(t0)        ; t0 = 0xFFFFFFFF`7FFFYYYY\n    ADDL    zero, t0, t0        ; t0 = 0x00000000`7FFFYYYY\n<\/pre>\n<p>Constants that are in the range <code>0x7FFF8000<\/code> to <code>0x7FFFFFFF<\/code> suffer from this problem.&sup1; <\/p>\n<p>All of this hassle about creating 32-bit constants <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20031008-00\/?p=42223\">has consequences for the Windows NT memory manager<\/a>, as I discussed a few years ago. <\/p>\n<p>Okay, so that&#8217;s it for loading constants. Next time, we&#8217;ll start looking at memory access. <\/p>\n<p><p>&sup1; There is a special shortcut for the value <code>0x7FFFFFFF<\/code>: <\/p>\n<pre>\n    LDA    t0, -1(zero)         ; t0 = 0xFFFFFFFF`FFFFFFFF\n    SRL    t0, #33, t0          ; t0 = 0x00000000`7FFFFFFF\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Building them up a piece at a time.<\/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-96785","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Building them up a piece at a time.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96785","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=96785"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96785\/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=96785"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96785"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96785"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}