Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

MIPS_primery_zadach / dandamudi05gtr guide risc processors programmers engineers

.pdf
Скачиваний:
65
Добавлен:
11.05.2015
Размер:
1.39 Mб
Скачать

Chapter 3 RISC Principles

 

 

 

41

 

 

Table 3.1 Characteristics of some CISC and RISC processors

 

 

 

 

 

 

 

 

 

 

 

 

 

CISC

 

RISC

 

 

 

 

 

 

 

 

 

Characteristic

 

VAX 11/780

 

Intel 486

MIPS R4000

 

 

 

 

 

 

 

 

Number of instructions

303

 

235

94

 

 

Addressing modes

 

22

 

11

1

 

 

Instruction size (bytes)

2–57

 

1–12

4

 

 

Number of general-purpose registers

16

 

8

32

 

 

 

 

 

 

 

 

 

 

 

R4

= (R2)

; load memory contents

 

 

 

 

R4

= R4+R3

; add contents of R3

 

 

 

 

(R2) = R4

; store the result

 

 

 

 

 

 

R2

= R2+1

; increment memory address

 

 

 

The CISC instruction, in general, executes faster than the four RISC instructions. That, of course, was the reason for designing complex instructions in the first place. However, execution of a single instruction is not the only measure of performance. In fact, we should consider the overall system performance.

Why RISC?

Designers make choices based on the available technology. As the technology—both hardware and software—evolves, design choices also evolve. Furthermore, as we get more experience in designing processors, we can design better systems. The RISC proposal was a response to the changing technology and the accumulation of knowledge from the CISC designs. CISC processors were designed to simplify compilers and to improve performance under constraints such as small and slow memories. The rest of the section identifies some of the important observations that motivated designers to consider alternatives to CISC designs.

Simple Instructions

The designers of CISC architectures anticipated extensive use of complex instructions because they close the semantic gap. In reality, it turns out that compilers mostly ignore these instructions. Several empirical studies have shown that this is the case. One reason for this is that different high-level languages use different semantics. For example, the semantics of the C for loop is not exactly the same as that in other languages. Thus, compilers tend to synthesize the code using simpler instructions.

42

Guide to RISC Processors

Few Data Types

CISC ISA tends to support a variety of data structures, from simple data types such as integers and characters to complex data structures such as records and structures. Empirical data suggest that complex data structures are used relatively infrequently. Thus, it is beneficial to design a system that supports a few simple data types efficiently and from which the missing complex data types can be synthesized.

Simple Addressing Modes

CISC designs provide a large number of addressing modes. The main motivations are

(i) to support complex data structures and (ii) to provide flexibility to access operands. Although this allows flexibility, it also introduces problems. First, it causes variable instruction execution times, depending on the location of the operands. Second, it leads to variable-length instructions. For example, the IA-32 instruction length can range from 1 to 12 bytes. Variable instruction lengths lead to inefficient instruction decoding and scheduling.

Large Register Set

Several researchers have studied the characteristics of procedure calls in HLLs. We quote two studies—one by Patterson and Sequin [22] and the other by Tanenbaum [28]. Several other studies, in fact, support the findings of these two studies.

Patterson and Sequin’s study of C and Pascal programs found that procedure call/return constitutes about 12 to 15% of HLL statements. As a percentage of the total machine language instructions, call/return instructions are about 31 to 33%. More interesting is the fact that call/return generates nearly half (about 45%) of all memory references. This is understandable as procedure call/return instructions use memory to store activation records. An activation record consists of parameters, local variables, and return values. In the IA-32, for example, the stack is extensively used for these activities. This explains why procedure call/return activities account for a large number of memory references. Thus, it is worth providing efficient support for procedure calls and returns.

In another study, Tanenbaum [28] found that only 1.25% of the called procedures had more than six arguments. Furthermore, more than 93% of them had less than six local scalar variables. These figures, supported by other studies, suggest that the activation record is not large. If we provide a large register set, we can avoid memory references for most procedure calls and returns. In this context, we note that the eight general-purpose registers available in IA-32 processors are a limiting factor in providing such support. The Itanium, for example, provides a large register set (128 registers), and most procedure calls on the Itanium can completely avoid accessing memory.

Chapter 3 RISC Principles

43

RISC Design Principles

The best way to understand RISC is to treat it as a concept to design processors. Although initial RISC processors had fewer instructions compared to their CISC counterparts, the new generation of RISC processors has hundreds of instructions, some of which are as complex as the CISC instructions. It could be argued that such systems are really hybrids of CISC and RISC. In any case, there are certain principles that most RISC designs follow. We identify the important ones in this section.

Simple Operations

The objective is to design simple instructions so that each can execute in one cycle. This property simplifies processor design. Note that a cycle is defined as the time required to fetch two operands from registers, perform an operation, and store the result in a register. The advantage of simple instructions is that there is no need for microcode and operations can be hardwired. If we design the cache subsystem properly to capture these instructions, the overall execution efficiency can be as good as a microcoded CISC machine.

Register-to-Register Operations

A typical CISC instruction set supports register-to-register operations as well as register- to-memory and memory-to-memory operations. The IA-32, for instance, allows register- to-register as well as register-to-memory operations; it does not allow memory-to-memory operations. The VAX 11/780, on the other hand, allows memory-to-memory operations as well.

RISC processors allow only special load and store operations to access memory. The rest of the operations work on a register-to-register basis. This feature simplifies instruction set design as it allows execution of instructions at a one-instruction-per-cycle rate. Restricting operands to registers also simplifies the control unit.

Simple Addressing Modes

Simple addressing modes allow fast address computation of operands. Because RISC processors employ register-to-register instructions, most instructions use register-based addressing. Only the load and store instructions need a memory-addressing mode. RISC designs provide very few addressing modes: often just one or two. They provide the basic register indirect addressing mode, often allowing a small displacement that is either relative or absolute.

Large Register Set

RISC processors use register-to-register operations, therefore we need to have a large number of registers. A large register set can provide ample opportunities for the com-

44

Guide to RISC Processors

piler to optimize their usage. Another advantage with a large register set is that we can minimize the overhead associated with procedure calls and returns.

To speed up procedure calls, we can use registers to store local variables as well as for passing arguments. Local variables are accessed only by the procedure in which they are declared. These variables come into existence at the time of procedure invocation and die when the procedure exits.

Fixed-Length, Simple Instruction Format

RISC designs use fixed-length instructions. Variable-length instructions can cause implementation and execution inefficiencies. For example, we may not know if there is another word that needs to be fetched until we decode the first word. Along with fixed-length instruction size, RISC designs also use a simple instruction format. The boundaries of various fields in an instruction such as opcode and source operands are fixed. This allows for efficient decoding and scheduling of instructions. For example, both PowerPC and MIPS use six bits for opcode specification.

Summary

We have introduced important characteristics that differentiate RISC designs from their CISC counterparts. CISC designs provide complex instructions and a large number of addressing modes. The rationale for this complexity is the desire to close the semantic gap that exists between high-level languages and machine languages.

In the early days, effective usage of processor and memory resources was important. Complex instructions tend to minimize the memory requirements. Empirical data, however, suggested that compilers do not use these complex instructions; instead, they use simple instructions to synthesize complex instructions. Such observations led designers to take a fresh look at processor design philosophy. RISC principles, based on empirical studies on CISC processors, have been proposed as an alternative to CISC. Most of the current processor designs are based on these RISC principles. The next part looks at several RISC architectures.

PART II

Architectures

4

MIPS Architecture

In the previous chapter, we discussed the RISC design principles. Starting with this chapter, we look at the architecture of several RISC processors. This chapter gives details about the MIPS architecture. However, we do not discuss its instruction set details here. We devote the next part of the book to this purpose.

Introduction

We have selected to present the MIPS as the first architecture. One of the reasons for this preference is the simplicity of the MIPS architecture and its faithfulness to the RISC design philosophy. Once you read details about the other architectures in the following chapters, you will see why this is so.

The MIPS architecture primarily grew out of research done at Stanford. Along with the Berkeley RISC project, these projects influenced processor design towards RISC orientation. MIPS is dominant in embedded applications including digital cameras, digital TVs, Sony PlayStation 2, network routers, and so on.

The MIPS Instruction Set Architecture (ISA) has evolved over time from MIPS I through MIPS V ISAs. In the late 1990s, MIPS formalized their designs around two basic architectures: MIPS32 for 32-bit architectures and MIPS64 for 64-bit architectures. The MIPS32 architecture is based on the MIPS II ISA with some additional instructions from MIPS III through MIPS V ISAs. The MIPS64 architecture is based on the MIPS V ISA.

MIPS first processor implementation R2000 was announced in the mid-1980s. An improved version R3000 became available three years later. Both these processors were 32-bit implementations. The first 64-bit MIPS implementation R4000 was released in the early 1990s. In the next part, which discusses the MIPS assembly language, we focus on the MIPS R2000/R3000 processor. The main reason for this selection is that the SPIM simulator is written for this processor. From a pedagogical perspective, this processor is sufficient to explain the MIPS assembly language.

47

48

Guide to RISC Processors

Like the other RISC processors, MIPS is based on the load/store architecture. As mentioned in Chapter 3, in this architecture most instructions expect their operands to be in registers. Two instructions are used to move data between registers and memory. As we show in the next part, the MIPS architecture provides several load and store instructions to transfer data of different sizes: byte, halfword, and so on.

In the rest of the chapter, we give details on the MIPS32 architecture. The instruction set and assembly language programming aspects are covered in the next part. We start our discussion with the registers set.

Registers

The MIPS32 architecture provides 32 general-purpose registers, a Program Counter (PC), and two special-purpose registers. All registers are 32-bits wide as shown in Figure 4.1. In the assembly language, these registers are identified as $0, $1, . . . , $31. Two of the general-purpose registers—the first and the last—are reserved for a specific function:

Register $0 is hardwired to provide zero. This register is often used as a source register when a zero value is needed. If this register is used as the destination register of an instruction, the result is discarded.

The last register $31 is used as a link register by the jump and link (jal) instruction, which is used to invoke a procedure. Register $31 is used to store the return address of a procedure call. We discuss details about this instruction in Chapter 11.

We discussed the purpose of the PC register in Chapter 2 (see page 22). The two special-purpose registers—called HI and LO—are used to hold the results of integer multiply and divide instructions:

In the integer multiply operation, HI and LO registers hold the 64-bit result, with the higher-order 32 bits in the HI and the lower-order 32 bits in the LO register.

In integer divide operations, the 32-bit quotient is stored in the LO and the remainder in the HI register.

Register Usage Convention

Although there is no requirement from the processor hardware, there is an established convention on how these 30 registers should be used. Table 4.1 shows the suggested use of each register. Because these suggestions are not enforced by the hardware, we can use the general-purpose registers in an unconventional manner. However, such programs are not likely to work with other programs.

Registers $v0 and $v1 are used to return results from a procedure. Registers $a0 to $a3 are used to pass the first four arguments to procedures. The remaining arguments are passed via the stack. These registers are not preserved across procedure calls (i.e., the called procedure can freely modify the contents of these registers).

Chapter 4 MIPS Architecture

49

31

0

zero

 

0

at

 

1

v0

 

2

v1

 

3

a0

 

4

a1

 

5

a2

 

6

a3

 

7

t0

 

8

t1

 

9

t2

 

10

t3

 

11

t4

 

12

t5

 

13

t6

 

14

t7

 

15

s0

 

16

s1

 

17

s2

 

18

s3

 

19

s4

 

20

s5

 

21

s6

 

22

s7

 

23

t8

 

24

t9

 

25

k0

 

26

k1

 

27

gp

 

28

sp

 

29

fp

 

30

ra

 

31

 

 

 

31

0

HI

LO

Multiply and divide registers

31

0

PC

Program counter

General−purpose registers

Figure 4.1 MIPS registers. All registers are 32-bits wide.

Registers $t0 to $t9 are temporary registers that need not be preserved across a procedure call. These registers are assumed to be saved by the caller. On the other hand, registers $s0 to $s7 are callee-saved registers that should be preserved across procedure calls.

50

 

 

Guide to RISC Processors

 

Table 4.1 MIPS registers and their conventional usage

 

 

 

 

 

 

Register name

Number

Intended usage

 

 

 

 

 

 

zero

0

Constant 0

 

$at

1

Reserved for assembler

 

$v0, $v1

2, 3

Results of a procedure

 

$a0, $a1, $a2, $a3

4–7

Arguments 1–4 (not preserved across

 

 

 

call)

 

$t0$t7

8–15

Temporary (not preserved across call)

 

$s0$s7

16–23

Saved temporary (preserved across call)

 

$t8, $t9

24, 25

Temporary (not preserved across call)

 

$k0, $k1

26, 27

Reserved for OS kernel

 

$gp

28

Pointer to global area

 

$sp

29

Stack pointer

 

$fp

30

Frame pointer (if needed);

 

 

 

otherwise, a saved register $s8

 

$ra

31

Return address (used to return from a

 

 

 

procedure)

 

 

 

 

 

Register $sp is the stack pointer, which is useful to implement the stack. It points to the top of stack. The MIPS compiler does not use a frame pointer. As a result, the frame pointer register $fp is used as callee-saved register $s8. The $ra is used to store the return address in a procedure call. We discuss these registers in Chapter 11.

Register $gp points to the memory area that holds constants and global variables. The $at register is reserved for the assembler. The assembler often uses this register to translate pseudoinstructions. Pseudoinstructions are not the processor instructions; these instructions are supported by the assembler. Each pseudoinstruction is translated by the assembler into one or more processor instructions. In the next part, we give some examples to show how the assembler uses this register in translating pseudoinstructions (see the examples on pages 229 and 281).

Addressing Modes

As MIPS is a load/store architecture, only the load and store instructions access memory. All other instructions expect their operands in the processor registers. Thus, they use register-addressing mode. For more details on the addressing modes, see our discussion in Chapter 2 on page 33.

Chapter 4 MIPS Architecture

51

It is important to understand how the load and store instructions access the operands located in memory. As noted in Chapter 3, CISC processors provide a large number of addressing modes. RISC processors, on the other hand, support only one or two addressing modes. MIPS faithfully follows this RISC principle.

The bare machine provides only a single memory-addressing mode:

disp(Rx)

where displacement disp is a signed, 16-bit immediate value. The address is computed as

disp + contents of base register Rx

We can use any register as the base register. MIPS uses the I-type instruction encoding for the load and store instructions. As you can see from this encoding the immediate value is restricted to a 16-bit signed number.

Even though there is only one basic addressing mode, we can make one of the two components zero to get variations on this basic addressing mode. For example, if we specify $0, the address is the immediate value specified as this register is hardwired to zero. Similarly, if we specify zero as the immediate value, it takes the contents of the specified register as the memory address. For example, if $a0 points to an array that contains 4-byte elements, we can specify the first element as 0($a0). If we want to access the next element, we can specify its address as 4($a0). In Chapter 12, we give some examples that use these addressing modes.

The virtual machine supported by the assembler provides additional addressing modes to help in assembly language programming. These addressing modes are described in detail in Chapter 12.

Instruction Format

MIPS, being a RISC processor, uses a fixed-length instruction format. Each instruction is 32 bits long as shown in Figure 4.2. It uses three different instruction formats.

Immediate (I-type): All load and store instructions use this instruction format. The immediate value is a signed, 16-bit integer. In addition, arithmetic and logical instructions that use an immediate value also use this format. Branch instructions use a 16-bit signed offset relative to the program counter and are encoded in this format.

Jump (J-type): Jump instructions that specify a 26-bit target address use this instruction format. These 26 bits are combined with the higher-order bits of the program counter to get the absolute address.

Register (R-type): Arithmetic and logical instructions use this instruction format. In addition, jump instructions in which the target address is specified indirectly via a register also use this instruction format.

Соседние файлы в папке MIPS_primery_zadach