You are on page 1of 8

Arrows and CPU

Emulation

Mittwoch, 10. Oktober 12


Simplified: a CPU is just
a bunch of states
instructions that modify those states
external stuff

Mittwoch, 10. Oktober 12


This is beautifully implemented as functions inside a State
Monad:
type MicrocodeMonad = State (Regs
Word32)

add :: Reg -> Word32 -> Microcode ()


add reg i = do
v <- readreg reg
writereg reg (v + i)

cmpxchg :: Reg -> Word32 -> Microcode ()


cmpxchg r1 r2 = do
eax <- readreg EAX
v1 <- readreg r1
v2 <- readreg r2
if eax == v1
then writereg r1 v2
else writereg' EAX v1
Mittwoch, 10. Oktober 12
Just for fun, we want to parallelize the CPU
add eax, ecx add ebx, 2
add eax, ecx
add ebx, 2
add eax, 2 add eax, 2 add ebx, ecx
add ebx, ecx
add eax, 2
add ebx, ecx add eax, 2 add ebx, ecx
add eax, ebx

add eax, ebx

We need to find out which registers an instruction affects

But isnt all that information in the Microcode already?

Mittwoch, 10. Oktober 12


Generalized Combination
An instruction consists of different parts
(readreg, writereg, ...), combined to bigger
parts
Combine register access maps (boolean fields
which are ored) of these parts
But (>>=) does not combine parts:
(>>=) :: m a -> (a -> m b) -> m b

We rather need:
? :: f a b -> f b c -> f a c

Mittwoch, 10. Oktober 12


Its not a Monad, its an Arrow!
data Microcode a b = Microcode {
ins :: Regs Bool, outs :: Regs Bool,
code :: (a, Regs Word32) -> (b, Regs Word32)
}
instance Arrow Microcode where ...

readreg :: Reg -> Microcode () Word32


readreg reg = Microcode {
ins = [ ... reg = True ... ],
outs = [ ... all False ...],
code = \(_,Regs r) -> (r ! reg, Regs r) }

> :t writereg EAX


writereg EAX :: Microcode Word32 ()
> :t readreg EAX >>> writereg EBX
readreg EAX >>> writereg EBX :: Microcode () ()

> ins (readreg EAX)


EAX
Mittwoch, 10. Oktober 12
We can inspect instructions to see which
registers they might affect:

> ins $ add EBX 5


EBX

> outs $ cmpxchg ECX EDX


EAX,ECX

And we can execute them:


> exec (fillRegs 10) $ add EBX 5
Regs (fromList [(EAX,10),(EBX,15), ...

Mittwoch, 10. Oktober 12


Arrow sugar is slightly different. Note the distinction
between combine time and runtime values!
readreg :: Reg -> Microcode () Word32
writereg :: Reg -> Microcode Word32 ()

cmpxchg :: Reg -> Reg -> Microcode () ()


cmpxchg r1 r2 = proc _ -> do
eax <- readreg EAX -< ()
v1 <- readreg r1 -< ()
v2 <- readreg r2 -< ()
if eax == v1
then writereg r1 -< v2
else writereg EAX -< v1

if-then-else is actually sugar for ArrowChoice, making


different combination/runtime semantics possible.

Mittwoch, 10. Oktober 12

You might also like