ISADesign:ARMDesign:A

Copyright 2018, Clinton A Staley

Concepts

  1. ARM machine language
  2. Data processing instructions

Overview

In this topic, we'll look a the bit-level format and design of the ARM ISA.

We've referred indirectly to the bit-level machine language in prior topics, when we mentioned, for instance, that a ldr offset is limited by the number of bits reserved for it in the instruction. And in the intro topic we looked at the layout of a sample add instruction. But now we'll go through the machine language design more thoroughly. It's not necessary to understand every instruction in it, but we will at least cover those instructions we've used so far, except for the floating point coprocessor instructions, which we'll get to in the next topic.

ARM Machine Language Overview

Look up, and consult as we go, a bit-level chart of the ISA, like the one on p 4-2 of the ARM Instruction Set reference from the course Bibliography. Or use the image in the notes, quoted from https://www.cs.uaf.edu/courses/cs301/2014-fall/notes/arm-asm/ at the University of Alaska. In-lecture questions will frequently ask you to look up information in the first reference, or comparable ones.

The chart shows the 32-bit layout of each type of ARM instruction. As you can see, there are a number of different configurations, for different types of instructions. Bits are numbered right to left, from 0 to 31. Some bits are fixed, e.g. the 00 in bits 26/27 in the Data Processing category. But most form bit fields indicating things like source or target registers (4 bits each), operands (12 bits), or just single option flags of one bit, like the S and I bits in Data Processing. A lot is being crammed into just 32 bits, and one of the interesting points of ISA design is the way in which we make the most out of the limited bits in an instruction.

Data Processing Instructions

Let's look more closely at the Data Processing format on the first row. Instructions in this category include mov, add, sub, mvn, rsb, and, orr, cmp and 8 others we haven't used yet.

Condition field

Like all the formats, it starts with a 4 bit cond field in the leftmost bits. This field specifies whether the operation is conditional on prior results. If an assembly instruction has a condition, like addeq or sublt, the two-letter condition is indicated by a 4-bit pattern in the cond field. One pattern (1110 in fact) is reserved to indicate "always" or unconditional execution, which is the most common case. So, a lot of ARM instructions begin with 1110, if they're not conditionally executed.

We've seen before that conditional operations allow the CPU to avoid pipeline-disrupting branches. It is interesting that this feature is so important that every machine language instruction can be conditional, and 4 out of 32 bits in every instruction are reserved to indicate the condition.

Question 1

Use the references to determine what 4-bit pattern would be at the start of an moveq instruction, and of a addlt instruction.

Answer 1

Patterns 0000 and 1011, respectively.

Data Processing

The next two bits are fixed at 00, and mark the instruction as a Data Processing instruction. Every category of instruction has its own unique set of fixed bits, which distinguishes it from any other category. We'll look more closely at the fixed bits later.

Following the 00 fixed bits is a single bitfield labelled I (That's an I, not a 1.) This bit affects how the final 12 bits for operand2 are interpreted. We'll discuss it when we get to operand2.

The next four bits labelled opcode indicate which type of data processing instruction to perform: add, sub and so on.

Question 2 Check the references again. What four-bit opcode pattern indicates an add? Which an rsb? Find and describe the eight data processing instructions we haven't seen in our example code thus far.

Answer 2

Page 4-10 in the ARM Instruction Set document mentioned earlier show that add is 0100, and rsb is 0011. The eight new instructions include adc, a form of add that includes the carry from a prior operation. This lets you do adds on 8 or more byte integers by adding the rightmost four byte pair, and then the next four bytes, including the carry from the prior add. Instruction sbc does the same for subtraction. There's eor which does an bitwise exclusive or. And cmp has three partner instructions, all of which do an test operation to set condition codes, like cmp. But, tst does an "and", teq does an exclusive or, and cmn does an addition. Apparently fine control over how testing is done, to save instructions in tight loops, is important. There's even the obscure bic, that performs a negate-and operation.

Following opcode is the S bit. While we typically set condition codes with a cmp (or tst, teq or cmn), any data processing instruction will set the condition codes if you set the S bit to 1. So we might write adds r1, r2, r3 (the s suffix sets the s bit) and then do a branch on the result of the add, e.g. beq label.

Registers

The Rd field in bits 12-15 (skipping the Rn for now -- some diagrams may label it Rs) gives the target register, as a four-bit binary number from 0 to 15. So, for instance, an add R1, R2, R3 has Rd of 0001, indicating register 1 as the target. The Rn field gives the first operand, so that same instruction has an Rn of 0010. Remember that the bits for the target register come after those for the first operand register.

Operand2

The second operand occupies 12 bits. We've seen a variety of possible second operands. Examples include:

 #42         constant 42 (or anything up to 255)
 R3          or any other register
 R4, lsr 3   R4 logic right-shifted by 3 or any value up to 31
 R4, asr R2  R4 arithmetic right-shifted by R2's value.

And something alluded to earlier: certain constants over 255 are permitted, e.g. 200, 512, or even 16,711,680. But, interestingly, not 257, or 513, or many others. We'll see why in a minute.

Getting all that out of 12 bits is a remarkable accomplishment, and the operand2 bits are among the most cleverly used in the ARM design, or in any ISA. They are used in two different ways, as determined by the aforementioned I bit. Let's go over each of those two ways.

Operand2 as a register and shift

If the I bit is 0, the operand2 bits represent a register and optional shift.

The first 8 bits describe the shift (S bits) and the last 4 the register (R bits), so the format is:

SSSSSSSSRRRR

The shift bits can represent either a constant shift, e.g. asr #12, or a shift by the value a register, e.g lsr r3. See page 4-12 in our reference doc for details.

Constant shift

If that last S bit is 0, it indicates a constant shift. The first 5 S bits give a 0 to 31 integer value indicating the amount to shift, and the next 2 bits give the shift type, e.g. 10 for asr. So the 8 shift bits for asr #12 are 01100 10 0. 011000 is 12. 10 is asr. 0 is constant shift. Putting it all together, a 12-bit operand2 representing r6, asr #12 is:

01100 10 0 0110

with the last four bits giving the register to shift: r6.

Register shift

If the last S bit is 1, then we have a register-determined shift, e.g. asr r4. The first four bits give the register containing the shift amount, the fifth bit is a fixed 0, and the next two give the shift type as for constant shift. So asr R4 is 0100 0 10 1. And the 12 bits for R6, asr R4 would be

0100 0 10 1 0110

Question 3

All of this is documented in the references. Use the discussion above, and the references, to determine the 12-bit operand2 patterns for:

R9, lsl #30
R3, asr R7
fp, ror #11  @ fp rotate-right-shifted by 11

Answer 3

R9, lsl #30 is 11110 00 0 1001

R3, asr R7 is 0111 0 10 1 0011

fp, ror #11 is 01011 11 0 1011 since fp is R11.

The ror is new; we haven't used it before. It specifies a rotating or circular shift to the right. (Recall this concept from the intermediate binary lecture.)

Question 4

There is no left circular shift. Why is one not needed?

Answer 4

If you want to circular shift to the left by, say, 8 bits, you can get the same result by circular shifting to the right by 24 bits. All circular shifts can be specified as right shifts (or as left shifts)

Question 5

Explain why a register-and-shift operand2 cannot have the pattern XXXX1XX1XXXX, where X is any bit value.

Answer 5

The second 1-bit means a register-determined shift, but such shifts require a 0 bit in the fifth bit position.

The illegality of that 12-bit pattern turns out to be important later.

Constant operand2

All of the preceding discussion was for the register-and-shift operand2. If the I bit is 1, then operand2's 12 bits represent a constant value instead of a possibly-shifted register, and the rules are completely different.

The easy way to use those 12 bits would be to let them represent a constant integer from 0 to 4095, which is the max unsigned integer value in 12 bits. A more conventional or older ISA might do just that. But the ARM designers decided to stretch those 12 bits in a clever way.

They realized that not all high integer values were equally likely to be needed, so they reserved just the bottom 8 bits for the integer constant, giving the range of 0 to 255 we've been assuming thus far. But, those 8 bits are viewed as the bottom byte in a 32 bit value (with the top 24 bits 0.) And, the top 4 bits of operand2 specify an amount to circular or rotate shift those bottom 8 bits, so that they can be moved about to get various larger constants.

Specifically, the top 4 bits give a value between 0 and 15. This is doubled to get possible shift values 0,2,4,....30. Odd-valued shifts are not possible. The shift is to the right, not the expected left. But, it's a circular right shift. So, for instance, a shift of 2 pushes the bottom two bits "around the bend" into the top two positions.

00000000000000000000000010100111 >> 2 gives 11000000000000000000000000101001

If you want to shift left by say, 4 bits, you specify a circular right shift of 28 bits, which is the same thing. Here are some examples of constant operand2 values:

1110 10100011 circular right shift of 14*2 = 28 => 00000000000000000000101000110000

0101 11000011 circular right shift of 5*2 = 10  => 00110000110000000000000000000000 

Question 6

What 32-bit constants do these operand2 constants represent: 100010100101, 110011000011, 000011011011.

Answer 6

1000 10100101 =>  00000000101001010000000000000000  (shift by 16)
1100 11000011 =>  00000000000000001100001100000000  (shift by 24)
0000 11011011 =>  00000000000000000000000011011011  (no shift)

Question 7

Try it the other way. For each of the values 4064, 32768, and 1028, construct an operand2 bit pattern that results in that value. Or, as will be the case for one of them, explain why it's not possible. Can any of them be represented in more than one way?

Answer 7

4064 is 254 << 4, so 111011111110. 32768 is 1 << 15, so 100100000010 or 101000001000, or several other patterns. 1028 is 257 << 4, but this cannot be represented because 257 is 100000001, and cannot fit into the bottom 8 bits.

Fortunately, you don't have to do all this by hand when coding in assembly. You simply give the constant you want in the instruction, and the assembler determines how to represent it, or gives an error if it cannot do so. So, add r1, r2, #32768 simply works. And mov r1, #1028 gets an error.

Some sample instructions

You now know enough to decode a data processing machine language instruction or two.

Question 8

Decode this instruction, giving the assembly language equivalent. You'll need to first translate hex to binary so you can see the bits, then break apart the fields, and if needed look up the significance of each by reviewing the lecture or the reference docs. Then write an English description of the instruction, and finally write the assembly for it.

E1874203

Answer 8

In hex: E1874203

In binary 11100001100001110100001000000011

By fields:  1110   00 0         1100 0  0111 0100 00100  00 0  0011
w/meanings always  dp reg/shift orr noS  r7  r4    sft 4  lsl reg r3

In English, that's always-execute, a dp-format instruction, with
register-and-shift operand2 format, an orr operation, don't set
condition codes, target register r4, operand 1 register r7,
operand2 is a constant shift of 4, logical shift left, on 
register r3
 
In assembly: orr r4, r7, r3, lsl #4

Question 9

Now go the other way, translating this instruction from assembly, to an English description, to a labelled fields representation, to binary and finally hex:

rsblt r0, r1, #3360

Answer 9


In assembly: rsblt r0, r1, #3360

In English: On condition lt, do a data processing rsb, with a constant operand2.  Target is r0, operand1 is r1, and operand2 is 3360, or 210*16, or 210 right-circular rotated by 32-4 = 28

By fields: 1101 00 1         0011 0  0001 0000 1110    11010010
w/meanings  lt  dp const op2 rsb  nS  r1   r0  ror 28    210

In binary: 1101 0010 0110 0001 0000 1110 1101 0010

In hex: B2610ED2

In the next lecture segment we'll look at the ldr/str and related formats.