2015-10-05

MIPS, part 3: Memory access instructions

Even on MIPS, with its plentiful registers, fast memory access is essential.

To make address resolution simpler for the processor, MIPS I only defines one addressing mode: register plus signed 16-bit offset. This allows it to resolve addresses in one cycle, no more, no less.

Memory load requests are first brought up to the data cache, which may service the load immediately. If the data cache doesn't have the requested data, one whole cache line of data is read using a memory burst command.

Memory store requests are first brought up to the store buffer. The cache line surrounding the write has to be loaded in order to preserve the surrounding bytes, but the store buffer allows more operations to be carried out while waiting for the cache line to be loaded. Then, the data is only written when the data cache line needs to be evicted for another memory access, using a memory burst command.

This setup can be bypassed if needed by using uncached memory access. However, most games, and most code within those games, will be using cached accesses. The data cache is very efficient for these accesses.

You'll want to read MIPS part 1: Registers and calling convention first.

MIPS, part 2: ALU instructions

Here are some common instructions in MIPS I and their effects. Some of those effects are important for optimization purposes, so they'll be described in greater detail.

These instructions are common on the Sony PlayStation. Counter-intuitively, they are also much more common than 64-bit instructions on the Nintendo 64: because its data bus is 32-bit, loading and storing 64-bit quantities to memory would take twice as long, so most games were written with 32-bit data and instructions only. Some games could even be run on a pure 32-bit MIPS processor!

You'll want to read MIPS part 1: Registers and calling convention first.

2015-09-25

MIPS, part 1: Registers and calling convention

In 1994 and 1995, Sony released its PlayStation console. It would soon be followed, in 1996 and 1997, by Nintendo's Nintendo 64 console. What both of them had in common, as briefly described in the entry "Why Old Games, New Tech?", was that they both contained processors running the MIPS architecture.

The MIPS architecture was a very large departure from the previous generation of consoles, sometimes known as the 16-bit era, due to the heavy focus on bits:

2015-09-20

Why Old Games, New Tech?

Welcome to Old Games, New Tech! This post should explain the name in addition to what I intend to put on this blog.

Old games – think games for the Nintendo Entertainment System (and its successor, the Super NES), Nintendo Game Boy, Sega Master System (and its successor, the Mega Drive, or Genesis), and arcade machines – had precious little ROM to hold their data and code. The consoles running the games also had processors with relatively low clock speeds, slow memory access, and no data cache. Most code was written directly in a given console's assembly language: the programmer was able to control every interaction between the processor and the slow main memory, which had an impact on both performance and code size. Code size was helped by the short instructions. However, it was hindered again when the programmer needed to perform calculations on values that were larger than 8 bits, as multiple instructions would be required.