{"id":102774,"date":"2019-08-08T07:00:00","date_gmt":"2019-08-08T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102774"},"modified":"2019-09-13T21:25:08","modified_gmt":"2019-09-14T04:25:08","slug":"20190808-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190808-00\/?p=102774","title":{"rendered":"The SuperH-3, part 4: Basic arithmetic"},"content":{"rendered":"<p>Okay, we&#8217;re ready to do some arithmetic. Due to the limited instruction encoding space, there isn&#8217;t room for any three-operand instructions.\u00b9 All of the arithmetic instructions are two-operand, where the second source operand also acts as the destination.<\/p>\n<pre>    ADD     Rm, Rn      ; Rn += Rm    , no effect on T\r\n    ADD     #imm, Rn    ; Rn += imm   , no effect on T\r\n    ADDC    Rm, Rn      ; Rn += Rm + T, T receives carry\r\n    ADDV    Rm, Rn      ; Rn += Rm    , T receives signed overflow\r\n<\/pre>\n<p>The <code>ADD<\/code> instructions add two values and put the result in the second register. You can add two registers together, or you can add a signed 8-bit immediate to the destination register.<\/p>\n<p>The <code>ADDC<\/code> instruction treats the <var>T<\/var> flag as a carry flag: It is added to the sum, and it receives the carry of the result.<\/p>\n<p>The <code>ADDV<\/code> instruction treats the <var>T<\/var> flag as an overflow flag: It reports whether a signed overflow occurred.<\/p>\n<p>Okay, subtraction is going to look really similar now.<\/p>\n<pre>    SUB     Rm, Rn      ; Rn -= Rm    , no effect on T\r\n    SUB     #imm, Rn    ; Rn -= imm   , no effect on T\r\n    SUBC    Rm, Rn      ; Rn -= Rm + T, T receives borrow\r\n    SUBV    Rm, Rn      ; Rn -= Rm    , T receives signed underflow\r\n<\/pre>\n<p>Basically the same as addition, except you&#8217;re now subtracting. The SH-3 treats <var>T<\/var> as a borrow flag in the case of <code>SUBC<\/code>, whereas for <code>SUBV<\/code> it reports whether a signed underflow occurred.<\/p>\n<p>Arithmetic negation is up next.<\/p>\n<pre>    NEG     Rm, Rn      ; Rn = -Rm    , no effect on T\r\n    NEGC    Rm, Rn      ; Rn = -Rm - T, T receives borrow\r\n<\/pre>\n<p>There is no <code>NEGV<\/code>, but overflow occurs only if the value is <code>0x80000000<\/code>, so I guess you could test for that value specifically.<\/p>\n<p>There is a special instruction for for decrementing a register:<\/p>\n<pre>    DT      Rn          ; Rn = Rn - 1, T  = (Rn == 0)\r\n<\/pre>\n<p>The <i>decrement and test<\/i> instruction decrements a register and compares the result against zero. This is presumably for counted loops.<\/p>\n<p>Next come the comparison instructions.<\/p>\n<pre>    CMP\/EQ #imm, r0     ; T = (r0 == signed 8-bit immediate)\r\n    CMP\/EQ Rm, Rn       ; T = (Rn == Rm)\r\n    CMP\/HS Rm, Rn       ; T = (Rn \u2265 Rm), unsigned comparison\r\n    CMP\/GE Rm, Rn       ; T = (Rn \u2265 Rm),   signed comparison\r\n    CMP\/HI Rm, Rn       ; T = (Rn &gt; Rm), unsigned comparison\r\n    CMP\/GT Rm, Rn       ; T = (Rn &gt; Rm),   signed comparison\r\n    CMP\/PZ Rn           ; T = (Rn \u2265 0),    signed comparison\r\n    CMP\/PL Rn           ; T = (Rn &gt; 0),    signed comparison\r\n    CMP\/STR Rm, Rn      ; T = 1 iff any corresponding bytes are equal\r\n<\/pre>\n<p>These instructions set the <var>T<\/var> flag according to a particular comparison. Note that the comparison is backward! For example, <code>CMP\/GE r1, r2<\/code> does not check whether <var>r1<\/var>\u00a0\u2265\u00a0<var>r2<\/var>; rather, it checks whether <var>r2<\/var>\u00a0\u2265\u00a0<var>r1<\/var>. <i>This takes a lot of getting used to.<\/i><\/p>\n<p>You have the special ability to compare <var>r0<\/var> for equality with a signed 8-bit immediate. Otherwise, you can compare two registers against each other, or a register against zero.<\/p>\n<p>The special <code>CMP\/STR<\/code> compares two registers to determine whether any of the four component bytes are equal. It&#8217;s clear from the mnemonic that the intended purpose is to search for a null terminator in a string. You set <var>Rn<\/var> to zero and then do a <code>CMP\/STR<\/code> against every longword in the string until it says, &#8220;Hey, I found a zero byte!&#8221; and then you can study that longword to see where the zero byte is.<\/p>\n<p>The processor documentation doesn&#8217;t explain why they chose the names for the mnemonics, but I can guess.<\/p>\n<table class=\"cp3\" style=\"border: solid 1px black; border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Condition<\/th>\n<th>Meaning<\/th>\n<\/tr>\n<tr>\n<td><code>EQ<\/code><\/td>\n<td>equal<\/td>\n<\/tr>\n<tr>\n<td><code>HS<\/code><\/td>\n<td>high or same<\/td>\n<\/tr>\n<tr>\n<td><code>GE<\/code><\/td>\n<td>greater or equal<\/td>\n<\/tr>\n<tr>\n<td><code>HI<\/code><\/td>\n<td>high<\/td>\n<\/tr>\n<tr>\n<td><code>GT<\/code><\/td>\n<td>greater than<\/td>\n<\/tr>\n<tr>\n<td><code>PZ<\/code><\/td>\n<td>plus or zero<\/td>\n<\/tr>\n<tr>\n<td><code>PL<\/code><\/td>\n<td>plus<\/td>\n<\/tr>\n<tr>\n<td><code>STR<\/code><\/td>\n<td>string<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>It took me a while to come up with a plausible explanation for <code>HS<\/code>.<\/p>\n<p><b>Exercise 1<\/b>: Synthesize the <code>SETT<\/code> and <code>CLRT<\/code> instructions.<\/p>\n<p><b>Exercise 2<\/b>: Perform the opposite of the <code>MOVT<\/code> instruction: Set the <var>T<\/var> register to 0 if a register is zero, or 1 if the register is nonzero.<\/p>\n<p>The last arithmetic instructions are the extension instructions.<\/p>\n<pre>    EXTS.B Rm, Rn       ; sign extend byte in Rm to Rn\r\n    EXTS.W Rm, Rn       ; sign extend word in Rm to Rn\r\n    EXTU.B Rm, Rn       ; zero extend byte in Rm to Rn\r\n    EXTU.W Rm, Rn       ; zero extend word in Rm to Rn\r\n<\/pre>\n<p>That&#8217;s it for the basic arithmetic instructions. We&#8217;ll start looking at the more complicated arithmetic instructions <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190809-00\/?p=102776\">next time<\/a>, starting with multiplication.<\/p>\n<p>\u00b9 Well, okay, you can have three-operand instructions if some of them are hard-coded! But that&#8217;s not what I mean. I mean three-operand instructions where the programmer can choose all three of the operands.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Basic elementary-school stuff.<\/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-102774","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Basic elementary-school stuff.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102774","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=102774"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102774\/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=102774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}