{"id":102784,"date":"2019-08-15T07:00:00","date_gmt":"2019-08-15T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102784"},"modified":"2019-09-13T21:40:52","modified_gmt":"2019-09-14T04:40:52","slug":"20190815-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190815-00\/?p=102784","title":{"rendered":"The SuperH-3, part 9: Constants"},"content":{"rendered":"<p>Loading constants on the SH-3 is a bit of a pain. <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190806-00\/?p=102752\"> We saw that the <code>MOV<\/code> instruction supports an 8-bit signed immediate<\/a>, but what if you need to load something outside that range?<\/p>\n<p>The assembler allows you to write this:<\/p>\n<pre>    MOV     #value, Rn      ; load constant into Rn\r\n<\/pre>\n<p>If the value fits in an 8-bit signed immediate, then it uses that. Otherwise, it chooses a PC-relative <code>MOV.W<\/code> or <code>MOV.L<\/code> depending on the size of the value, and it generates the constant into the code at a point it believes that the code is unreachable, such as two instructions after a <code>bra<\/code> or <code>rts<\/code>. If no such point can be found, the assembler raises an error. You can use the <code>.nopool<\/code> directive to prevent constants from being generated at a particular point, or <code>.pool<\/code> to force them to be generated.<\/p>\n<p>If the compiler can generate the constant in two instructions, typically by combining an immediate with a shift, then the compiler will tend to prefer the two-instruction version instead of using a constants pool, especially if it can put the second half of the calculation into an otherwise-wasted branch delay slot. (Yes, we haven&#8217;t learned about branch delay slots yet. Be patient.)<\/p>\n<pre>    ; for -256 \u2264 value &lt; 256, multiples of 2\r\n    MOV    #value \/ 2, Rn\r\n    SHLL   Rn\r\n\r\n    ; for -512 \u2264 value &lt; 512, multiples of 4\r\n    MOV    #value \/ 4, Rn\r\n    SHLL2  Rn\r\n\r\n    ; for -65536 \u2264 value &lt; 65536, multiples of 256\r\n    MOV    #value \/ 256, Rn\r\n    SHLL8  Rn\r\n\r\n    ; for -16777216 \u2264 value &lt; 16777216, multiples of 65536\r\n    MOV    #value \/ 65536, Rn\r\n    SHLL16 Rn\r\n<\/pre>\n<p>Other instructions that could be useful for building constants are logical right shift and rotate. I&#8217;m not going to write them out, though. Use your imagination.<\/p>\n<p>Now, it may seem cumbersome to have to use two instructions to generate a constant, but remember that these instructions are only 16 bits in size, so you can fit two of them in the space of a single MIPS, PowerPC, or Alpha AXP instruction. And if you can schedule the instructions properly, the fact that the SH-3 is dual-issue means that each of the instructions executes in a half-cycle, so the pair of them takes a single cycle, assuming you can schedule another instruction between them.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190816-00\/?p=102788\"> Next up are the control transfer instructions<\/a>, and the return of the confusing branch delay slot, but the SH-3 adds more wrinkles to make them even more confusing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Squeezing constants into a tiny instruction.<\/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-102784","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Squeezing constants into a tiny instruction.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102784","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=102784"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102784\/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=102784"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102784"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102784"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}