Difference between revisions of "Introducing the Instruction Set Part 4"

From Intellivision Wiki
Jump to: navigation, search
Line 20: Line 20:
 
Logical shifts (SLL, SLR, SLLC) fill the newly-opened positions with zeros.  Arithmetic shifts (SAR, SARC) fill the newly opened positions with copies of bit 15.  Logical right shifts can be thought of as "unsigned divide by 2", whereas arithmetic right shifts can be thought of as "signed divide by 2, rounding toward negative."
 
Logical shifts (SLL, SLR, SLLC) fill the newly-opened positions with zeros.  Arithmetic shifts (SAR, SARC) fill the newly opened positions with copies of bit 15.  Logical right shifts can be thought of as "unsigned divide by 2", whereas arithmetic right shifts can be thought of as "signed divide by 2, rounding toward negative."
  
You can combine shift and add instructions to perform simple multiplications.  The following example shows how to multiply the value in R0 by 20, using R1 as a temporary variable.
+
== Caveats ==
 +
 
 +
Shift instructions are [[Non-interruptible Instructions]].  Be sure to include an interruptible instruction in a long sequence of shifts or other non-interruptible instructions, otherwise you could cause display glitches.
 +
 
 +
== Using Shifts for Multiplication ==
 +
 
 +
Shifting values left multiplies them by powers of two.  Each bit position shifted corresponds to another power of two.  Shifting left one position multiplies by 2; shifting by two positions multiplies by 4.  The following table illustrates the relationship between positions shifted and the power of two.  The table stops at 8 for brevity's sake.
 +
<TABLE BORDER>
 +
<TR><TH>Number of positions shifted left</TH><TH>Power of 2 multiplied by</TH><TH>Example Code Sequence</TH></TR>
 +
<TR><TD ALIGN=center>1</TD><TD ALIGN=center>2</TD><TD><CODE><pre>    SLL Rx, 1 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>2</TD><TD ALIGN=center>4</TD><TD><CODE><pre>    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>3</TD><TD ALIGN=center>8</TD><TD><CODE><pre>    SLL Rx, 1
 +
    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>4</TD><TD ALIGN=center>16</TD><TD><CODE><pre>    SLL Rx, 2
 +
    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>5</TD><TD ALIGN=center>32</TD><TD><CODE><pre>    SLL Rx, 1
 +
    SLL Rx, 2
 +
    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>6</TD><TD ALIGN=center>64</TD><TD><CODE><pre>    SLL Rx, 2
 +
    SLL Rx, 2
 +
    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>7</TD><TD ALIGN=center>128</TD><TD><CODE><pre>    SLL Rx, 1
 +
    SLL Rx, 2
 +
    SLL Rx, 2
 +
    SLL Rx, 2 </pre></CODE></TD></TR>
 +
<TR><TD ALIGN=center>8</TD><TD ALIGN=center>256</TD><TD><CODE><pre>    SWAP Rx, 1
 +
    ANDI #$FF00, Rx</pre></CODE></TD></TR>
 +
</TABLE>
 +
 
 +
You can combine shift and add instructions to perform simple multiplications by constants that aren't powers of two.  The following example shows how to multiply the value in R0 by 20, using R1 as a temporary variable.
 
<CODE><pre>
 
<CODE><pre>
 
     SLL  R0, 2  ; Multiply R0 by 4
 
     SLL  R0, 2  ; Multiply R0 by 4
Line 27: Line 56:
 
     ADDR R1, R0  ; Add (value * 4) to (value * 16), giving (value * 20)
 
     ADDR R1, R0  ; Add (value * 4) to (value * 16), giving (value * 20)
 
</pre></CODE>
 
</pre></CODE>
 +
 +
== Using Shifts for Division by Powers of Two ==
  
 
Right shifts divide by powers of two, but they also truncate the fractional portion.  You can combine a right shift with an ADCR to get a rounded result instead:
 
Right shifts divide by powers of two, but they also truncate the fractional portion.  You can combine a right shift with an ADCR to get a rounded result instead:
Line 33: Line 64:
 
     ADCR R0      ; Add 1 if shifted away bit was 1.  (Round towards positive)
 
     ADCR R0      ; Add 1 if shifted away bit was 1.  (Round towards positive)
 
</pre></CODE>
 
</pre></CODE>
 +
 +
 +
== Combining Shifts and Rotates for Extended-Precision Shifts ==
  
 
Rotate instructions combined with shift instructions make it easy to shift values longer than 16 bits.  The following examples show how to shift the 32 bit number held in R1:R0 left and right by 1 and 2 positions.  (R1 holds bits 16..31 of the 32-bit number.)
 
Rotate instructions combined with shift instructions make it easy to shift values longer than 16 bits.  The following examples show how to shift the 32 bit number held in R1:R0 left and right by 1 and 2 positions.  (R1 holds bits 16..31 of the 32-bit number.)

Revision as of 23:25, 8 October 2007

This short tutorial examines the shift instructions. If you haven't read Part 1 or Part 2 yet, you might consider doing so first.

Shift and Rotate Instructions

The CP1610 offers a rich variety of shift and rotate instructions. These are useful for bit manipulation and certain types of mathematics. Shifting left by one position is equivalent to multiplying by 2. Shifting right by one position is roughly equivalent to dividing by 2. The shift instructions only operate on R0 through R3. You cannot use them with R4 through R7. Overall, CP-1600 offers 8 separate shift instructions. Each can shift by one or two positions.

Click on a given mnemonic to see how it operates.

  SLL   Rx[, 2]Shift Logical Left
  SLR   Rx[, 2]Shift Logical Right
  SAR   Rx[, 2]Shift Arithmetic Right
  SWAP  Rx[, 2]Swap bytes
  SLLC  Rx[, 2]SLL into Carry
  SARC  Rx[, 2]SAR into Carry
  RLC   Rx[, 2]Rotate Left thru Carry
  RRC   Rx[, 2]Rotate Right thru Carry

Logical shifts (SLL, SLR, SLLC) fill the newly-opened positions with zeros. Arithmetic shifts (SAR, SARC) fill the newly opened positions with copies of bit 15. Logical right shifts can be thought of as "unsigned divide by 2", whereas arithmetic right shifts can be thought of as "signed divide by 2, rounding toward negative."

Caveats

Shift instructions are Non-interruptible Instructions. Be sure to include an interruptible instruction in a long sequence of shifts or other non-interruptible instructions, otherwise you could cause display glitches.

Using Shifts for Multiplication

Shifting values left multiplies them by powers of two. Each bit position shifted corresponds to another power of two. Shifting left one position multiplies by 2; shifting by two positions multiplies by 4. The following table illustrates the relationship between positions shifted and the power of two. The table stops at 8 for brevity's sake.

Number of positions shifted leftPower of 2 multiplied byExample Code Sequence
12
    SLL Rx, 1 
24
    SLL Rx, 2 
38
    SLL Rx, 1
    SLL Rx, 2 
416
    SLL Rx, 2
    SLL Rx, 2 
532
    SLL Rx, 1
    SLL Rx, 2
    SLL Rx, 2 
664
    SLL Rx, 2
    SLL Rx, 2
    SLL Rx, 2 
7128
    SLL Rx, 1
    SLL Rx, 2
    SLL Rx, 2
    SLL Rx, 2 
8256
    SWAP Rx, 1
    ANDI #$FF00, Rx

You can combine shift and add instructions to perform simple multiplications by constants that aren't powers of two. The following example shows how to multiply the value in R0 by 20, using R1 as a temporary variable.

    SLL  R0, 2   ; Multiply R0 by 4
    MOVR R0, R1  ; Save a copy of original value * 4
    SLL  R0, 2   ; Multiply R0 by 4 again (original value * 16)
    ADDR R1, R0  ; Add (value * 4) to (value * 16), giving (value * 20)

Using Shifts for Division by Powers of Two

Right shifts divide by powers of two, but they also truncate the fractional portion. You can combine a right shift with an ADCR to get a rounded result instead:

    SARC R0, 1   ; Signed divide by 2.  Shifted away bit goes to 'C'
    ADCR R0      ; Add 1 if shifted away bit was 1.  (Round towards positive)


Combining Shifts and Rotates for Extended-Precision Shifts

Rotate instructions combined with shift instructions make it easy to shift values longer than 16 bits. The following examples show how to shift the 32 bit number held in R1:R0 left and right by 1 and 2 positions. (R1 holds bits 16..31 of the 32-bit number.)

    ; Shift R1:R0 left by 1 position
    SLLC R0, 1   ; Shift lower half left, extra bit to 'C'
    RLC  R1, 1   ; Shift upper half left, pulling lower bit from 'C'
    
    ; Shift R1:R0 left by 2 positions
    SLLC R0, 2   ; Shift lower half left, extra bits to 'C', 'O'
    RLC  R1, 2   ; Shift upper half left, pulling lower bit from 'C', 'O'
    
    ; Shift R1:R0 right by 1 position (arithmetic right shift)
    SARC R1, 1   ; Shift upper half left, extra bit to 'C'
    RRC  R0, 1   ; Shift lower half left, pulling lower bit from 'C'
    
    ; Shift R1:R0 left by 2 positions (arithmetic right shift)
    SARC R1, 2   ; Shift upper half right, extra bits to 'C', 'O'
    RRC  R0, 2   ; Shift lower half right, pulling lower bit from 'C', 'O'


Moving On

At this point, you may wish to continue with the remaining parts of this tutorial:

Or, you can return to the Programming Tutorials index.