{"id":1268,"date":"2019-08-12T22:24:36","date_gmt":"2019-08-12T22:24:36","guid":{"rendered":"http:\/\/retroramblings.net\/?p=1268"},"modified":"2019-08-24T20:48:57","modified_gmt":"2019-08-24T20:48:57","slug":"the-eightthirtytwo-isa-2","status":"publish","type":"post","link":"https:\/\/retroramblings.net\/?p=1268","title":{"rendered":"Nailing Down the Instruction Set"},"content":{"rendered":"\n<p><strong>The EightThirtyTwo ISA &#8211; Part 3 &#8211; 2019-08-12<\/strong><\/p>\n\n\n\n<p>My initial plan for the EightThirtyTwo ISA was to define eight general purpose registers, and use the ninth &#8220;temp&#8221; register as an accumulator.  Immediate values would be assigned here, as would the result of any arithmetic operations.  The best way to test the concept is, of course, to write some actual code.  So let&#8217;s see what simple looping looks like with this concept:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  li 99 \/\/ (needs two li instructions since 99 doesn't fit within a signed 6-bit value)<br>  mr r0<br>.bottles_of_beer:<br>  \/\/ take one down, pass it around<br>  li 1<br>  sub r0<br>  mr r0<br>  cond NEQ  \/\/ Disable execution if we've reached zero<br>  li .bottles_of_beer<br>  mr r7   \/\/ if not, do another iteration<br>  cond EX \/\/ return to normal execution  <\/pre>\n\n\n\n<p>That&#8217;s not too bad &#8211; weighing in at 10 bytes &#8211; way better than MIPS, but 68K beats us easily thanks to its dbf instruction.  Let&#8217;s try something more involved&#8230;<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>The first thing I&#8217;m going to want to do with this ISA, if I succeed in turning it into an actual CPU core, is to build a SOC similar to the one used in the ZPU Demos project.  This SOC defines a UART at address 0xffffffc0.  This register has &#8216;tx ready&#8217; and &#8216;rx ready&#8217; flags as well as the actual data.  Writing to this register looks something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&nbsp; li 0xffffffc0 \/\/ UART register (needs two li instructions)<br>&nbsp; mr r0<br>&nbsp; li msg<br>&nbsp; mr r1<br>.loop<br>&nbsp; ld r0 \/\/ read UART status<br>&nbsp; mr r2<br>&nbsp; li 0x100 \/\/ tx ready? (needs two li instruction)<br>&nbsp; and r2<br>&nbsp; cond EQ<br>&nbsp; im .loop<br>&nbsp; mr r7<br>&nbsp; cond EX<br><br>&nbsp; ld r1&nbsp;&nbsp;&nbsp; ; For simplicity, ignore byte extraction for the moment.<br>&nbsp; cond NEQ<br>&nbsp; st r0<br>  li 1<br>  add r1<br>  mr r1<br>&nbsp; im .loop<br>&nbsp; mr r7<br>&nbsp; cond EX<br>.done&nbsp;&nbsp;&nbsp; \/\/ 23 instructions \/ bytes<\/pre>\n\n\n\n<p>We ignored byte extraction in the above code snippet, but that&#8217;s clearly something that we need.  It would look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  ld r0    \/\/ read 32-bits, assuming that the SOC will ignore bits 0 and 1 of the address.<br>  mr r1&nbsp;&nbsp;&nbsp; \/\/ 32-bit word<br>&nbsp; im 3<br>&nbsp; and r0&nbsp;&nbsp;&nbsp; \/\/ mask off all but lowest two bits<br>  mr r0<br>&nbsp; im 3<br>&nbsp; exg r0<br>&nbsp; sub r0&nbsp;&nbsp;&nbsp; \/\/ subtract from 3 - how many times do we need to shift<br>  mr r0<br>&nbsp; im 3<br>&nbsp; shl r0&nbsp;&nbsp;&nbsp; \/\/ multiply by 8<br>&nbsp; lsr r1&nbsp;&nbsp;&nbsp; \/\/ shift word by that many bits<br>&nbsp; im 255<br>  and r1  \/\/ 14 instructions<\/pre>\n\n\n\n<p>That&#8217;s quite a lot of code, and since byte manipulation is a common operation this suggests that adding byte load and store instructions would be worthwhile if I can possibly find room for them.  Since it&#8217;s unusual to access bytes in isolation, I&#8217;ll implement load and store both with post-increment, since this is the most common use case.<\/p>\n\n\n\n<p>What I&#8217;m also noticing is that every time I use an arithemetic or logic instruction I&#8217;m immediately writing the result to a register, because I can&#8217;t build an immediate value with &#8216;li&#8217; without overwriting what&#8217;s in the accumulator.  The only way to avoid this is to pre-generate immediates and write them to registers in advance.  In this and some other experimental code snippets, code density and ease of programming seems to be slightly improved if the result goes directly to the nominated register intead of to the temp register.  (There is one important exception to this, which I will cover in a later part.)<\/p>\n\n\n\n<p><strong>For this reason, I have decided that the result of arithmetic and logic instructions will now go to the register nominated in the instruction, rather than to the temp register.<\/strong><\/p>\n\n\n\n<p>The semi-final instruction set, which I think is more-or-less chosen now (unless I hit major implementation problems!), looks like this:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>cond &#8211; enable conditional execution, 3-bit operand specifies the condition, one of EQual, NotEQual, StrictlyLessThan, LessthanorEqual, StrictlyGreatherThan, GreaterthanorEqual, EX(ecute) or N(o)EX(ecute)<\/li><li>mt &#8211; move register to temp<\/li><li>mr &#8211; move temp to register<\/li><li>exg &#8211; exchange register with temp<\/li><li>ldi &#8211; load indexed (nominated register + r5) [may be removed &#8211; I haven&#8217;t tried using it yet]<\/li><li>st &#8211; store to memory pointed to by rn<\/li><li>ld &#8211; load from memory pointed to by rn<\/li><li>sti &#8211; store indexed (nominated register + r5) [may be removed &#8211; I haven&#8217;t tried using it yet]<\/li><li>add<\/li><li>cmp<\/li><li>ldinc &#8211; load and post-increment (for stack)<\/li><li>sub<\/li><li>stdec &#8211; store and post-decrement (for stack)<\/li><li>and<\/li><li>or<\/li><li>xor<\/li><li>addt &#8211; add and transfer registers old contents to temp.  (Used for PC-relative branches, but could also have uses in indexing.)<\/li><li>shl &#8211; shift left<\/li><li>asr &#8211; arithmetic shift right<\/li><li>lsr &#8211; logical shift right<\/li><li>ror &#8211; rotate right<\/li><li>rorc &#8211; rotate right through carry [may be removed &#8211; I haven&#8217;t tried using it yet]<\/li><li>stbinc &#8211; store byte with post increment<\/li><li>ldbinc &#8211; load byte with post increment<\/li><li>li &#8211; load immediate<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The EightThirtyTwo ISA &#8211; Part 3 &#8211; 2019-08-12 My initial plan for the EightThirtyTwo ISA was to define eight general purpose registers, and use the ninth &#8220;temp&#8221; register as an accumulator. Immediate values would be assigned here, as would the &hellip; <a href=\"https:\/\/retroramblings.net\/?p=1268\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,8],"tags":[],"class_list":["post-1268","post","type-post","status-publish","format-standard","hentry","category-fpga","category-hardware"],"_links":{"self":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1268","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1268"}],"version-history":[{"count":4,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1268\/revisions"}],"predecessor-version":[{"id":1281,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1268\/revisions\/1281"}],"wp:attachment":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}