Skip to main content
Engineering LibreTexts

5.4: Implementing the flexible operand (operand2)

  • Page ID
    76117
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Extending the mla example above, it follows that if the multiplication unit can be used in front of the ALU, the barrel shifter can be used for the same purpose. When the barrel shifter is used in this way, the result of the barrel shifting operation is called an operand2.

    The 3-address instructions in Chapter 4 are all examples of ARM assembly instructions that use the operand2. They were simplified by restricting the operand2 to use only the format where it was one immediate or one register value. This is why the 3-address assembly is valid ARM assembly, but just a subset of ARM assembly.

    The operand2 works by first shifting the value in the Rm by the value in Rs, and passing the shiftedvaluetotheALUwheretheALUoperationisperformed. Thisisillustratedinthefollowing diagrams. This is again a two-step instruction. In the first step, the Rm register value and the ShAmt value are passed to the barrel shifter. The barrel shifter applies the shift from the ShiftType and Rs to the value in Rm.

    Screen Shot 2022-03-24 at 3.28.37 PM.png

    Figure 29: MSCPU Operand2 operation - Step 1

    In the next step the value from the barrel shifter and value in the Rn register are passed to the ALU where the correct operation is performed.

    Screen Shot 2022-03-24 at 3.29.30 PM.png

    Figure 30: MSCPU Operand2 operation - Step 2

    The rest of this section illustrates how the instructions from Chapter 3 will be changed when the Operand2 is applied to the instructions.

    5.4.1 Operand2 syntax

    The Operand2 thus has the following format:

            <k> := even number less than 32
            <m> := any 32 bits that contains all zeros except for one grouping of less than 8 bits that can contain 1’s
            <n> := any number < 32
    <immediate> := # <m> | # <m>,<k> 
        <ShAmt> := # <n> | # <n>,<k> 
      <ShValue> := <ShAmt | register>
      <shiftOp> := <ShType> # <ShValue>
       <ShType> := lsl | lsr | asr | ror | rrx
     <register> := <Rm> | <Rm> , <shiftOp>
     <operand2> := <immediate> | <register>
    

    This definition divides the operand2 into two large semantic groups, immediate and register types. The next subsection will handle the immediate type of operand2 and the following section the register type of operand2.

    5.4.2 Operand2 immediate Semantics

    The simplest way to understand the immediate value is as an 8-bit number from (0...255) that can be rotated in the by k bits in using the ror operation in the 32-bit register. An example of this is representing 256. 256 is too large to be represented in an 8-bit number, but all of the bits are 0 except the \(9^{\rm th}\) bit. Thus 256 can be represented by an 8-bit value of 1 that is rotated right by 24 bits to put it in the \(9^{\rm th}\) bit position. Thus the 1, 0x0000001, is rotated 24 bits right (which is the same as rotating it 8 bits left), and becomes 0x00000010.

    Thus, the number 256 can be used as an immediate in ARM assembly. The following instruction is valid:

        MOV r2, #256

    Note that 256 cannot be represented in 8 bits, but it can be represented as the value of 1 rotated by 24 bits. This is equivalent of the following mov command:

        MOV r2, #1, 24

    These two MOV instructions are exactly equivalent, as the assembler will attempt to fix-up any immediate constant it is given. The fix up tries to represent the value as a group of 8-bits containing 0 and 1 bits, with all the other bits being 0. This group of 8 bits are then rotated until the desired number is achieved.

    While there are many numbers that can be represented using an 8-bit rotated value, there are more than cannot. For example, the number 256 requires 9 bits to represent it. This value will not be able to be fixed-up, and an attempt to run the following line of code:

        MOV r2, #257

    produces the error message,

        error: invalid constant (101) after fixup

    Using the Operand2 with the MVN operation will effectively double the number of constants that can be represented. For example, the number -257 can be specified as follows:

        MVN r2, #1, 24
    

    The Operand2 can be used with most of the data processing operators with some exceptions, such as MOV, MUL, and all shifts. Thus, constants greater than 256 can be used in the following ADD instruction.

       ADD r1, r2, #4096
    

    To a programmer not familiar with this 8-bit rotation format, the representable constants might seem arbitrary. For example, the ADD instruction works for numbers #256 and #260, but fails for the numbers #257, #258, and #259.

    Values that are not valid as a single immediate value can be built using MOV and ORR instructions. For example, to load the ASCII characters A, B, C, and D into r1 can be done with the following series of instructions:

        MOV r2,     #0x00000064
        ORR r2, r2, #0x00006300
        ORR r2, r2, #0x00620000
        ORR r2, r2, #0x61000000
    

    Finally, all of the 3-address operations from chapter 3 (with the exception of multiply and shift instructions) are real ARM instructions that simply include the Operand2. For example, the ADD operation which was defined for an immediate in Chapter 3 as:

      ADD Rd, Rn, Operand2
    

    5.4.3 Operand2 Register Semantics

    When using a register as the Operand2 value, the value is either just the value of Rm, or the value of Rm shifted in some manner. While the immediate instruction only allowed the Operand2 to be implemented using the ror operation to be applied to an even immediate value, any type of shift (lsl, lsr, asr, ror, rrx) can be specified when using the register semantics. Also, the amount of the shift can be specified either with the ShAmt or a register value. Thus, the following are valid formats of register shifts:

       MOV r1, r2, #4
       MOV r1, r2, lsl #3
       MOV r1, r2, asr r3
       MOV r1, r2, ror r4
       MOV r1, r2, rrx
    

    All of the 3 address instructions (again, except for multiply and shifts) from Chapter 4 actually have a format (illustrated using the ADD operation) of:

        ADD Rd, Rn, Operand2
    

    By applying the Operand2 to these instructions, many different instructions can be produced:

        ADD r1, r2, r3, LSL 2   // multiply r3 by 4 before adding, useful for                        
                                // array addressing
        ADD r1, r2, r3, ASR #1  // useful for division by 2, for example to find                            
                                // parent nodes in a Complete Binary Tree
        ADD r1, r2, r3, LSR r1  // logically shift the value in r3 by the amount                            
                                // in r1 before adding it to r3
    

    5.4.4 Syntax for Load/Store

    The Load/Store syntax from Chapter 4 is unchanged when an immediate value is used. However, if the instruction is a register instruction, it will use a Scaled Register Format. A Scaled Register Format is similar to a Register Format Operand2, but it is limited in that the shift amount must be a numeric value (the shift amount cannot be a register).


    This page titled 5.4: Implementing the flexible operand (operand2) is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Charles W. Kann III via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.

    • Was this article helpful?