Title: CS 2200 Lecture 4 Instruction Set Architectures ISAs
1CS 2200 Lecture 4Instruction Set Architectures
(ISAs)
- (Lectures based on the work of Jay Brockman,
Sharon Hu, Randy Katz, Peter Kogge, Bill Leahy,
Ken MacKenzie, Richard Murphy, and Michael
Niemier)
2How does code translate to instuctions?
- g h A8
- load s0,8(s3)
- actually
- lw s0,8(s3) lw dest, offset(base)
- add s1, s2, s0 add dst, src1, src2
- Notice Registers contain data or addresses!!
3Slightly more complex
- A12 h A8
- Compile it?
- lw s0, 8(s3)
- add s0, s2, s0
- sw s0, 12(s3)
4Variable Array Index?
- g h Ai
- add a0, s2, s3 i addr(A)
- lw a1, 0(a0) a1 ? Ai
- add s0, s1, a1 g ? h Ai
5Flashback How many registers?
- Early machines had about 1 (Accumulator)
- PDP-11 series had 8
- Typical 32 bit processors today have 32.
- Why not more?
- What happens when there are more variables than
registers? - Spillage Putting less commonly used variables
back into memory.
6Mips Register Conventions
Name
R
Usage
Preserved on call
zero
0
The constant value 0
n.a.
at
1
Reserved for assembler
n.a.
v0-v1
2-3
Values for results and expression evaluation
no
a0-a3
4-7
Arguments
no
t0-t7
8-15
Temporaries
no
s0-s7
16-23
Saved
yes
t8-t9
24-25
More temporaries
no
k0-k1
26-27
Reserved for use by operating system
n.a.
gp
28
Global pointer
yes
sp
29
Stack pointer
yes
fp
30
Frame pointer
yes
ra
31
Return address
yes
7LC2200 Register Conventions
Name
R
Usage
Preserved on Call
zero
0
The constant value 0
n.a.
at
1
Reserved for assembler
n.a.
v0
2
Return value
no
a0-a4
3-7
Argument or temporary
no
s0-s3
8-11
Saved general purpose registers
yes
k0
12
Reserved for OS/traps
n.a.
sp
13
Stack pointer
yes
fp
14
Frame pointer
yes
ra
15
Return address
yes
8Decisions, decisions...
- The affects of branch instructions are a big
source of research in computer architecture - In this class
- Jump will refer to unconditional changes in
control - Branch will refer to conditional changes in
control - And there are 4 main types of control-flow
change - Conditional branches (most frequent)
- Jumps
- Procedure calls
- Procedure returns
9which break down like this
s for benchmark Suite on load/store machine
10Where jumps and branches go
- Always to some specified destination address
- Most often, address is specified in instruction
- Procedure return is an exception however
- (Return target is not known at compile time)
- Usually, address specified relative to the PC
- PC Program Counter indexes executing
instructions - Control instructions specified as such are
PC-relative - Good b/c target often near current instruction
(indexed by PC) specified by fewer bits - Allows for position independence program can
run independently of where its loaded
11Target Unknown
- So what about these unknown addresses?
- Target NOT known at compile time
- Cant use PC relative must specify target
dynamically so we can change it at runtime - Some options
- Put target address in a register
- Let jump permit any addr. mode to supply target
address - Register indirect jumps useful for following
constructs - Case/Switch select among one of several
alternatives - Dynamically shared libraries library loaded
when invoked - No compile time target load from memory with
register indirect jump
12Some basic branch facts
- Branches usually use PC-relative addressing
- But how far is target from instruction?
- The answer to this question will tell us
- Which branch offsets to support
- How long an instruction is/how it should be
encoded - Note the gory interdependencies!!!
- Most branches are in the forward direction and
only 4-7 instructions away - Short displacement should suffice
- increased code density w/shorter instructions
13How do we know where to go?
Often branch is simple inequality test or
compares with 0 architectures make this is a
special case and make it fast!
14if statement
- if (i j) goto L1
- f g h
- L1 f f - i
- beq s3, a4, L1 if ij goto L1
- add s0, s1, s2 f g h
- L1 sub s0, s0, s3 f f - i
15Did we just use a go to???
16if statement
- if (i ! j)
- f g h
- f f - i
- beq s3, a4, L1
- add s0, s1, s2
- L1 sub s0, s0, s3
17if-then-else
-
- if (i j)
- f g h
- else
- f g
- beq s3, a4, Then if opp is T
- add s0, s1, zero f g h
- beq zero, zero, Exit
- Then add s0, s1, s2 f g h
- Exit
reg
contents
s0
f
s1
g
s2
h
s3
i
a4
j
The LC2200 has no BNE
18Loop with Variable Array Index
- Loop g g Ai
- i i j
- if (i ! h) goto Loop
reg
contents
s0
g
s1
h
s2
i
s3
j
Loop add a1, s2, a0 lw a1,
0(a1) add s0, s0, a1 add
s2, s2, s3 beq s2, s1, Exit
beq zero, zero, Loop Exit
a0
addr of A
Plus some temps
19While Loop
reg
contents
- while (savi k)
- i i j
- Loop add a1, s1, s0
- lw a2, 0(a1)
- beq a2, s3, Skip
- beq zero, zero, Exit
- Skip add s1, s1, s2
- beq zero, zero, Loop
- Exit
s0
addr(sav)
s1
i
s2
j
s3
k
a1
temp
a2
temp
20Case/Switch
- switch (k)
- case 0 f i j break
- case 1 f g h break
- case 2 f g - h break
- case 3 f i - j break
-
- slt t3, s5, zero If k lt 0
- bne t3, zero, Exit Exit
- slt t3, s5, t2 If k gt 4
- beq t3, zero, Exit Exit
- add t1, s5, s5 mpy k by 4
- add t1, t1, t1
Mips
21Case/Switchcontinued
- switch (k)
- case 0 f i j break
- case 1 f g h break
- case 2 f g - h break
- case 3 f i - j break
-
Jmptbl Address(L0) Address(L1) Address(L2)
Address(L3)
22Case/Switchcontinued
- switch (k)
- case 0 f i j break
- case 1 f g h break
- case 2 f g - h break
- case 3 f i - j break
add t1, t1, t4 t1 Jmptabk lw t0,
0(t1) jr t0 jump based
on reg t0 L0 add s0, s3, s4 j
Exit etc...
23Procedures (the previous examples were just
if statements, case statements, and loops what
about something like a function call)
24Procedures
- Procedure abstraction
- What is the programmers model?
- What does the compiler have to do?
- Remember functions are not compiled at the same
time - Simple hardware to support procedures?
25What do we need?
- What do we need to support procedure calls in
assembly language? - Nested modules/Recursion
- Pass values to modules
- Return value(s) from module
- Asynchronous compilation
- Need to do things in a uniform way
- Continue execution after module finishes
26Another way to look at it
- What does a programmer expect?
- 1. arguments bound to formal parameters
- 2. space for local variables
- 3. means to return a value (or values)
- 4. arbitrary nesting of procedure invocations
- e.g. for recursion
foo() bar(int a)
bar(42) int temp 3
... return(temp a)
27Procedure Issues
- Hardware instructions to support this model?
- Call/return
- Remember where we are in the program. Why?
- Program counter (PC)
- What should happen on every instruction
execution? - Would we need a PC if there were no procedure
abstraction? - Load/store
- Stack
- Push and pop
- Stack pointer (sp)
- Stack frames
- What do we store and restore on call/return?
28More procedure issues
- Software conventions (Why?)
- Reserve some of registers for parameters,
return values, return address - e.g. LC2200
- 5 for params, 1 for return values, one for return
address - JALR ltproc-addr in reggt, ra (ra is
return-addr) - JALR ra, zero Where does this go?
- What if we have more params or return values?
- Common use stack/memory
- Registers used in procedures
- Temporary registers
- Caller does not expect value to be preserved upon
return - LC2200 a0 to a4
- Saved registers
- Caller does expect value to be preserved on
return - LC2200 s0 to s3 (simplifies amount of state to
be saved)
29MIPS Registers
FYI
30LC2200 Registers
Recall
31A simple example
foo addi a0, zero, 42 constant
addi at, zero, bar jalr at, ra
jump-and-link ...
halt bar addi s0, zero, 3
temp 3 add v0, a0, s0 a
temp jalr ra, zero return!
32Procedure calls
- Its not just a matter of going somewhere else
we also may need to save state - At least return address must be saved (the PC)
- Some architectures provide a mechanism to save
registers, others make compiler do it - Two basic conventions used
- Caller saving Calling procedure must save the
registers it wants to use after return - Callee saving Called procedure must save the
registers it wants to use after return - Most compilers conservatively caller save any
variable that might be accessed during a call
33Procedure call issues to think about
- Assume procedure P1 calls procedure P2
- Both procedures manipulate global variable x
- If P1 put x in a register, it needs to tell P2
about it - But what if P2 calls P3 which uses a register
where x was put by P1? And P3 shouldnt touch
x. - Some programs may work more efficiently with the
caller saving, others might benefit from callee
saving. - Most sophisticated compilers use a combination of
both for maximum efficiency